Java 中的静态方法和非静态方法之间共享的资源



我知道static synchronized方法锁定在class对象上,而实例synchronized方法锁定在对象的当前实例上,即 this .

由于这两个对象是不同的,它们有不同的锁,所以当一个线程执行static synchronized方法时,java中的另一个线程不需要等待该线程返回,而是它将获得单独的锁。

考虑以下示例

public class Test {
  static int count = 0;
  public synchronized void f1(){
    count++;
  }
  public static synchronized void f2(){
    count++;
  }
}

此处的共享计数不是以相互互斥的方式访问的,这可能会导致在另一个线程使用static f2()方法递增count时,将不正确的count传递给f1()的调用方。

这种情况的解决方案是什么?我问的问题是否正确,如果不是,请让我正确?如果这是一个真实的情况,那么java pr避免了什么解决方案?

您可以在非静态方法上使用同步块,它应使用与静态同步方法相同的监视器:

public void f1() {
   synchronized(Test.class) {
     count++;
   }
}

经验法则是,静态同步方法应仅用于保护静态变量,而非静态同步方法应仅用于保护非静态变量。

由于count是静态的,因此从具有非静态同步的块修改它是不正确的。要正确编码并避免代码重复,请从f1调用f2,如下所示:

public void f1(){
    ... // Do something ...
    f2();
    ... // Do something else ...
}
public static synchronized void f2(){
    count++;
}

最新更新