同步静态方法和非静态方法的区别
在java中同步静态方法和非静态方法有什么区别?谁能用一个例子解释一下.另外同步一个方法和同步一个代码块有什么区别吗?
解决方案我将尝试添加一个示例以使这一点更加清晰.
如前所述,Java 中的同步是 Monitor 的实现概念.当您将代码块标记为同步时,您使用一个对象作为参数.当一个执行线程来到这样的代码块时,它必须首先等待,直到在同一对象的同步块中没有其他执行线程.
Object a = new Object();对象 b = 新对象();...同步(一){做东西();}...同步(b){doSomeStuff();}...同步(一){做其他东西();}
在上面的示例中,运行 doOtherStuff()
的线程会阻止另一个线程进入保护 doStuff()
的代码块.但是,线程可以毫无问题地进入 doSomeStuff()
周围的块,因为它在 Object b
上同步,而不是在 Object a
上同步.p>
当您在实例方法(非静态方法)上使用同步修饰符时,它与使用this"作为参数的同步块非常相似.所以在下面的例子中,methodA()
和 methodB()
的作用是一样的:
公共同步无效方法A(){做东西();}...公共无效方法B(){同步(这个){做东西();}}
请注意,如果您在该类中有一个未同步且没有同步块的 methodC()
,则不会阻止线程进入该方法,粗心的编程可能会让该线程访问对象中的非安全代码.
如果你有一个带 synchronized 修饰符的静态方法,它实际上与有一个以 ClassName.class
作为参数的同步块相同(如果你有该类的对象,ClassName cn = new ClassName();
,您可以使用 Class c = cn.getClass();
)
class ClassName {公共无效静态同步静态方法A(){doStaticStuff();}公共静态无效静态方法B(){同步(ClassName.class){doStaticStuff();}}公共无效非静态方法C(){同步(this.getClass()){做东西();}}公共静态无效 unSafeStaticMethodD() {doStaticStuff();}}
所以在上面的例子中,staticMethodA()
和 staticMethodB()
的作用是一样的.正在执行的线程也将被阻止访问 nonStaticMethodC()
中的代码块,因为它正在同一个对象上进行同步.
但是,重要的是要知道没有什么可以阻止正在执行的线程访问 unSafeStaticMethodD()
.即使我们说静态方法在 Class 对象上同步",也并不意味着它会同步对该类中方法的所有访问.它只是意味着它使用 Class 对象进行同步.非安全访问仍然是可能的.
What is the difference between synchronizing a static method and a non static method in java?Can anybody please explain with an example. Also is there any difference in synchronizing a method and synchronizing a block of code?
解决方案I will try and add an example to make this extra clear.
As has been mentioned, synchronized in Java is an implementation of the Monitor concept. When you mark a block of code as synchronized you use an object as a parameter. When an executing thread comes to such a block of code, it has to first wait until there is no other executing thread in a synchronized block on that same object.
Object a = new Object();
Object b = new Object();
...
synchronized(a){
doStuff();
}
...
synchronized(b){
doSomeStuff();
}
...
synchronized(a){
doOtherStuff();
}
In the above example, a thread running doOtherStuff()
would block another thread from entering the block of code protecting doStuff()
. However, a thread could enter the block around doSomeStuff()
without a problem as that is synchronized on Object b
, not Object a
.
When you use the synchronized modifier on an instance method (a non-static method), it is very similar to having a synchronized block with "this" as the argument. So in the following example, methodA()
and methodB()
will act the same way:
public synchronized void methodA() {
doStuff();
}
...
public void methodB() {
synchronized(this) {
doStuff();
}
}
Note that if you have a methodC()
in that class which is not synchronized and does not have a synchronized block, nothing will stop a thread from entering that method and careless programming could let that thread access non-safe code in the object.
If you have a static method with the synchronized modifier, it is practically the same thing as having a synchronized block with ClassName.class
as the argument (if you have an object of that class, ClassName cn = new ClassName();
, you can access that object with 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();
}
}
So in the above example, staticMethodA()
and staticMethodB()
act the same way. An executing thread will also be blocked from accessing the code block in nonStaticMethodC()
as it is synchronizing on the same object.
However, it is important to know that nothing will stop an executing thread from accessing unSafeStaticMethodD()
. Even if we say that a static method "synchronizes on the Class object", it does not mean that it synchronizes all accesses to methods in that class. It simply means that it uses the Class object to synchronize on. Non-safe access is still possible.
相关文章