同步静态方法和非静态方法的区别
在java中同步静态方法和非静态方法有什么区别?任何人都可以用一个例子来解释一下。此外,同步方法和同步代码块有什么区别吗?
在java中同步静态方法和非静态方法有什么区别?任何人都可以用一个例子来解释一下。此外,同步方法和同步代码块有什么区别吗?
我将尝试添加一个示例来使这一点更加清晰。
如前所述,在 Java 中同步是监视概念的实现。将代码块标记为已同步时,使用对象作为参数。当执行线程到达这样的代码块时,它必须首先等待,直到同一对象上的同步块中没有其他执行线程。
Object a = new Object();
Object b = new Object();
...
synchronized(a){
doStuff();
}
...
synchronized(b){
doSomeStuff();
}
...
synchronized(a){
doOtherStuff();
}
在上面的示例中,运行的线程将阻止另一个线程进入保护 的代码块。但是,线程可以毫无问题地进入块,因为它在 上同步,而不是 。doOtherStuff()
doStuff()
doSomeStuff()
Object b
Object a
当您在实例方法(非静态方法)上使用同步修饰符时,它与具有以“this”作为参数的同步块非常相似。因此,在下面的示例中,并将以相同的方式运行:methodA()
methodB()
public synchronized void methodA() {
doStuff();
}
...
public void methodB() {
synchronized(this) {
doStuff();
}
}
请注意,如果该类中有一个未同步且没有同步块,则没有任何内容会阻止线程进入该方法,并且不小心编程可能会让该线程访问对象中的非安全代码。methodC()
如果您有一个带有同步修饰符的静态方法,则它实际上与具有与参数一起的同步块是一回事(如果您有该类的对象,则可以使用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();
}
}
所以在上面的例子中,并采取同样的方式。执行线程也将被阻止访问 中的代码块,因为它正在同一对象上进行同步。staticMethodA()
staticMethodB()
nonStaticMethodC()
但是,重要的是要知道没有任何东西会阻止执行线程访问 。即使我们说静态方法“在 Class 对象上同步”,也不意味着它同步对该类中方法的所有访问。它只是意味着它使用 Class 对象进行同步。不安全的访问仍然是可能的。unSafeStaticMethodD()
简而言之,如果在静态方法上进行同步,则将在类(对象)上进行同步,而不是在实例(对象)上进行同步。这意味着在执行静态方法时,整个类都被阻止。因此,其他静态同步方法也被阻止。