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

2022-09-01 05:31:18

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


答案 1

我将尝试添加一个示例来使这一点更加清晰。

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

Object a = new Object();
Object b = new Object();
...
synchronized(a){
    doStuff();
}
...
synchronized(b){
    doSomeStuff();
}
...
synchronized(a){
    doOtherStuff();
}

在上面的示例中,运行的线程将阻止另一个线程进入保护 的代码块。但是,线程可以毫无问题地进入块,因为它在 上同步,而不是 。doOtherStuff()doStuff()doSomeStuff()Object bObject a

当您在实例方法(非静态方法)上使用同步修饰符时,它与具有以“this”作为参数的同步块非常相似。因此,在下面的示例中,并将以相同的方式运行:methodA()methodB()

public synchronized void methodA() {
  doStuff();
}
...
public void methodB() {
    synchronized(this) {
        doStuff();
    }
}

请注意,如果该类中有一个未同步且没有同步块,则没有任何内容会阻止线程进入该方法,并且不小心编程可能会让该线程访问对象中的非安全代码。methodC()

如果您有一个带有同步修饰符的静态方法,则它实际上与具有与参数一起的同步块是一回事(如果您有该类的对象,则可以使用ClassName.classClassName 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();
  }
}

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

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


答案 2

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


推荐