如何控制静态方法和实例方法之间的同步访问

时间:2011-06-07 12:58:58

标签: java concurrency synchronization static-methods

我正在研究Java中的Threads,它让我对如何控制类的静态方法和实例方法之间的同步访问感到好奇,因为类中静态方法的同步独立于对象的实例方法的同步。类。

目前,我在现实生活中找不到任何情况,所以我做了一个假设:

两个A和B类,A类具有静态方法,其形式参数为B类,实例方法也是如此。然后我创建两个线程来同时执行两个A方法。

保持以下 obj 状态的方法总是一致的?

class B { ... }
class A {
      public synchronized void instanceMethod(B obj){ ... }; 
      public static synchronized void staticMethod(B obj){ ... };

      public static void main(String[] args){
            B obj = new B();
            // create a Thread to modify the state of obj with A's instanceMethod
            // create a Thread to modify the state of obj with A's staticMethod
      }
}

4 个答案:

答案 0 :(得分:2)

A的静态方法不能改变对象A的this状态,因此你没有问题。

非静态方法可以修改静态字段。但是,如果您避免这样做,并且只使用静态方法来修改静态字段,则可以同步每个方法,它将正常工作。

锁定一个对象并修改不相关的对象是没有意义的。如果要修改B,则应该同步其方法,并且可能不需要在A上使用同步方法。

你能写一个更清晰的例子来编译吗?

class B { 
      public synchronized alter() { };
}
class A {
      public void instanceMethod(B obj){ obj.alter(); }; 
      public static void staticMethod(B obj){ obj.alter(); };

      public static void main(String[] args){
            B obj = new B();
            // create a Thread to modify the state of obj with A's instanceMethod
            // create a Thread to modify the state of obj with A's staticMethod
            obj.alter();
      }
}

答案 1 :(得分:2)

同步对象“B”。

public void instanceMethod(B obj) {
    synchronized(obj) {
        //no other thread will enter a synchronized block on 'obj' since we leave it
        ...
        obj.doSomething();
        ...
        obj.doSomethingElse(); //I can trust here that no other thread manipulated 'obj' since 2 lines before.
        ...
    }
}

静态方法相同。

答案 2 :(得分:1)

在静态锁定对象上进行同步,而不是同步方法调用。如果您想引入与这些方法同步的其他方法,这会给您带来额外的簿记责任:抓住它们的锁定。

class B { ... }
class A {
      static Object myLock = new Object();
      public void instanceMethod(B obj){ synchronized(myLock) {...} }; 
      public static void staticMethod(B obj){ synchronized(myLock) {...} };

      public static void main(String[] args){
            B obj = new B();
            // create a Thread to modify the state of obj with A's instanceMethod
            // create a Thread to modify the state of obj with A's staticMethod
      }
}

答案 3 :(得分:0)

听起来你好像担心B obj的状态...而不是同步A的方法,让B的实例方法在内部对B的每个实例进行适当的锁定。否则可能会有一个类C,不遵循锁定规则,你再次处于不一致的状态。