2013-02-21 58 views
0

经过一番快速搜索,我无法找到明确的答案。全班同步的成员方法

是否有一些更优雅的方法来同步整个类的整个成员方法(绑定实例)?这意味着方法可以由多个线程在多个实例上调用,但当时只能由一个线程调用。它也可以写成一个同步块。

(为了说明,该方法插入它的实例到共享高速缓存中。)

class DataObject { 

    public putInCache() { 
    synchronized(getClass()) { 

     // ... do some stuff 
     cache.insert(this); 
     // ... do some more stuff 

    } 
    } 

} 
+0

'DataObject'和'MyOtherDataObject'(它扩展了'DataObject')共享一个锁吗?或有单独的? – 2013-02-21 12:58:40

回答

6

这是避免在同步公开访问的对象是一个好主意。您可以使用一个共享的监控对象,但是:

class DataObject { 

    private static final Object cacheLock = new Object(); 

    public putInCache() { 
    synchronized(cacheLock) { 

     // ... do some stuff 
     cache.insert(this); 
     // ... do some more stuff 

    } 
    } 
} 

请注意,这个特定的实现DataObject和所有类都从它派生将共享锁。

5

Classinstance之间的差异是同步的。
实例同步作用于Object的每个实例,所以代码:

public synchronized void putInCache() { 
     // ... do some stuff 
     cache.insert(this); 
     // ... do some more stuff 
    } 

和代码

public void putInCache() { 
    synchronized(this) { 
     // ... do some stuff 
     cache.insert(this); 
     // ... do some more stuff 
    } 
    } 

在对等同他们不允许超过一个线程进入synchronized块同时;但是,这仅适用于课程上的每个实例。即在显示器上this

类同步作用于Class本身,下面的两个块也相当于:

public static synchronized void putInCache() { 
     // ... do some stuff 
     cache.insert(this); 
     // ... do some more stuff 
    } 
    public void putInCache() { 
    synchronized(MyClass.class) { 
     // ... do some stuff 
     cache.insert(this); 
     // ... do some more stuff 
    } 
    } 

他们不允许超过一个线程都同时进入synchronized块跨越JVM,即显示器在Class实例上,因此是独一无二的。

您需要使用Class同步。

另一种方法是锁定资源本身,因为这是您试图阻止并发访问;提供的资源不能为空和资源的实例不会随意改变 - 甚至更好,如果是final你可以这样做:

public void putInCache() { 
    synchronized(cache) { 
     // ... do some stuff 
     cache.insert(this); 
     // ... do some more stuff 
    } 
    } 

这使得它非常清楚为什么要锁定和你锁定的东西。

+0

我认为最好在资源本身上同步我的情况。谢谢。 – Radium 2013-02-22 13:59:56

0

我想你正在寻找班级同步。尝试使该方法成为静态和同步的方法。 如:

public synchronized static putInCache(){ 
//..your code 
} 

,这将意味着“方法可以由多个线程多个实例调用,但只能由当时一个线程。”

+0

是的,这也是可能的。但是我的例子稍有不同,我不想让这个方法成为静态的。感谢您的建议。 – Radium 2013-02-22 13:56:23