同步静态方法和非静态方法之间的区别

Amm*_*mmu 29 java synchronization

在java中同步静态方法和非静态方法有什么区别?任何人都可以用一个例子来解释.同步方法和同步代码块有什么区别吗?

Dan*_*ark 77

我将尝试添加一个示例,以使此更清楚.

如前所述,Java中的synchronized是Monitor概念的一种实现.将代码块标记为已同步时,请使用对象作为参数.当执行线程进入这样的代码块时,它必须首先等待,直到该同一对象上的同步块中没有其他正在执行的线程.

Object a = new Object();
Object b = new Object();
...
synchronized(a){
    doStuff();
}
...
synchronized(b){
    doSomeStuff();
}
...
synchronized(a){
    doOtherStuff();
}
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,运行的线程doOtherStuff()将阻止另一个线程进入代码保护块doStuff().但是,一个线程可以在doSomeStuff() 没有问题的情况下进入块,因为它是同步的Object b,而不是Object a.

在实例方法(非静态方法)上使用synchronized修饰符时,它与具有"this"作为参数的synchronized块非常相似.因此,在下面的例子中,methodA()methodB()会采取同样的方式:

public synchronized void methodA() {
  doStuff();
}
...
public void methodB() {
    synchronized(this) {
        doStuff();
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果您methodC()在该类中没有同步且没有同步块,则没有任何东西会阻止线程进入该方法,粗心的编程可能会让该线程访问该对象中的非安全代码.

如果你有一个带有synchronized修饰符的静态方法,它实际上与将一个synchronized块ClassName.class作为参数一样(如果你有一个该类的对象ClassName cn = new ClassName();,你可以访问该对象Class c = cn.getClass();)

class ClassName {
  public void static synchronized staticMethodA() {
    doStaticStuff();
  }
  public static void staticMethodB() {
    synchronized(ClassName.class) {
      doStaticStuff();
    }
  }
  public void nonStaticMethodC() {
    synchronized(this.getClass()) {
      doStuff();
    }
  }
  public static void unSafeStaticMethodD() {
   doStaticStuff();
  }
}
Run Code Online (Sandbox Code Playgroud)

所以在上面的例子中,staticMethodA()staticMethodB()采取同样的方式.nonStaticMethodC()当正在同一对象上同步时,执行线程也将被阻止访问代码块.

但是,重要的是要知道没有任何东西会阻止正在执行的线程访问unSafeStaticMethodD().即使我们说静态方法"在Class对象上同步",也不意味着它同步对该类中方法的所有访问.它只是意味着它使用Class对象进行同步.仍然可以进行非安全访问.


Pet*_*Mmm 19

简而言之,如果您在静态方法上进行同步,则将在类(对象)上进行同步,而不是在实例(对象)上进行同步.这意味着在执行静态方法时,整个类都被阻止.因此其他静态同步方法也被阻止.

  • ......如果他们也是同步的. (2认同)