【发布时间】:2014-03-11 13:43:57
【问题描述】:
我正在阅读有关 java 线程的内容,并且碰巧阅读了 this 博客。 在博客中我看到了一个声明:
在同步方法执行期间,线程持有该方法对象的监视器,或者如果该方法是静态的,它持有该方法的类的监视器。
谁能告诉我有什么区别:
- 一个线程正在为方法对象持有监视器
- 一个线程持有方法类的监视器
【问题讨论】:
标签: java multithreading synchronization
我正在阅读有关 java 线程的内容,并且碰巧阅读了 this 博客。 在博客中我看到了一个声明:
在同步方法执行期间,线程持有该方法对象的监视器,或者如果该方法是静态的,它持有该方法的类的监视器。
谁能告诉我有什么区别:
【问题讨论】:
标签: java multithreading synchronization
意思是同步的实例方法大致等价于:
public class FooClass {
public void foo() {
synchronized(this) {
...
}
}
}
而同步静态方法大致等价于:
public class FooClass {
public static void foo() {
synchronized(FooClass.class) {
...
}
}
}
所以在实例方法的情况下,它将在FooClass 的实例上同步(并且在其他线程中调用foo 在其他实例上不会阻塞),而在静态方法的情况下它在 Class 对象本身上同步。
请注意,对于静态方法版本,重要的是 包含该方法的类 - 即使该方法在概念上被称为“在”子类(例如 SubFooClass.foo())上,该方法仍然会获得声明它的类上的监视器。
更多详情请见JLS section 8.4.3.6。
【讨论】:
你可以粗略地翻译,在课堂上Foo,说:
public synchronized foo()
{
doSomething();
}
到:
public foo()
{
synchronized(this) {
doSomething();
}
}
鉴于:
public static synchronized foo()
{
doSomething();
}
(大致)翻译为:
public static foo()
{
synchronized(Foo.class) {
doSomething();
}
}
在第一种情况下,您与Foo (this) 的当前实例同步。在第二种情况下,您与Class 对象同步(所有Class 对象都是单例,这就是它起作用的原因)。
【讨论】:
在非静态方法上,锁在实例上(this);即你的方法相当于:
public void method(){
synchronised(this){
//my code
}
}
在静态方法上,没有实例(您不能在静态方法中引用 this)。所以锁在实际的类对象(MyObject.class)上。
public static void method(){
synchronised(MyClass.class){
//my code
}
}
因此,使用 1 个同步方法和 1 个同步静态方法,两者可以同时执行,因为它们不会阻止它们并行运行,锁在不同的对象上。
【讨论】: