我发现了两种同步方法:
第一:
public static Integer number = 0;
public synchronized static void myMethod(){
number++;
number--;
}
第二:
public static Integer number = 0;
private static final Object mySemaphoreLock = new Object();
public static void myMethod(){
synchronized (mySemaphoreLock){
number++;
number--;
}
}
这两种方法是否相同?它们之间有什么区别?
答案 0 :(得分:3)
在第二种情况下,锁对象仅对您的类可用。 在第一种方法中,其他一些代码可能会意外地或有意地获得锁,并使您的代码无法按预期工作。
例如,如果是第一种情况,则可以执行以下操作
public class MyBadClass {
public static void badStuff() { //Acquire lock on class object and do forever loop. Because of that you will not be able to call YourClass.myMethod() in your first option
synchronized (YourClass.class) {
while(true);
}
}
}
答案 1 :(得分:1)
这两种方法使用不同的对象进行同步(类实例与类字段)。
您的第一种方法:
public synchronized static void myMethod(){
number++;
number--;
}
可以表示为
public static void myMethod(){
synchronized (YourClass.class) {
number++;
number--;
}
}
因此您要使用的对象(YourClass
的类对象与类的静态字段(mySemaphoreLock
)上的同步对象比
public static void myMethod() {
synchronized (mySemaphoreLock) {
number++;
number--;
}
}
在您的示例中没有区别,但是您不能排除其他人(请考虑第三方代码) 也要在类的对象上进行同步(原因未知)-这会影响您的代码的行为。 通常,其他代码将执行以下操作:
class SomeOtherClass {
public void someOtherMethod() {
// for some reason SomeOtherClass synchronizes on YourClass.class
synchronized (YourClass.class) {
/* long running operation */
}
}
}
因此,即使您并行调用YourClass.myMethod()
,一个人也需要等待另一个人完成。
如果选择使用mySemaphoreLock
的实现,那将不会发生-这段代码将同时执行(因为它们使用不同的对象进行同步)-因此没有竞争。