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