我知道static
synchronized
方法锁定在class
对象上,而实例synchronized
方法锁定了当前的Object实例,即this
。
由于这两个对象都不同,因此它们具有不同的锁定,因此当一个线程正在执行static
synchronized
方法时,java中的其他线程不需要等待该线程返回,而是获得单独的锁。
考虑以下示例
public class Test {
static int count = 0;
public synchronized void f1(){
count++;
}
public static synchronized void f2(){
count++;
}
}
此处不以互斥方式访问共享计数,这可能导致将count
传递给f1()
的调用方,而另一个线程正在使用count
{{递增static
1}}方法。
这种情况的解决方案是什么?我问的是正确的问题,如果没有请让我正确吗?如果这是一个真实的情况,那么java pr ovoids会有什么解决方案?
答案 0 :(得分:3)
您可以在非静态方法上使用synchronized块,它应该使用与静态同步方法相同的监视器:
public void f1() {
synchronized(Test.class) {
count++;
}
}
答案 1 :(得分:3)
经验法则是静态同步方法应仅用于保护静态变量,而非静态同步方法应仅用于保护非静态变量。
由于count
是静态的,因此从具有非静态同步的块修改它是不正确的。要正确编码并避免代码重复,请从f2
致电f1
,如下所示:
public void f1(){
... // Do something ...
f2();
... // Do something else ...
}
public static synchronized void f2(){
count++;
}