2种同步方式,有什么区别

时间:2018-09-23 19:32:34

标签: java synchronized

我发现了两种同步方法:

第一:

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--;
        }
    }

这两种方法是否相同?它们之间有什么区别?

2 个答案:

答案 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的实现,那将不会发生-这段代码将同时执行(因为它们使用不同的对象进行同步)-因此没有竞争。