我正在阅读有关java线程的文章,并且正好阅读了this博客。 在博客中我发现了一个声明:
在执行synchronized方法期间,线程保存该方法对象的监视器,或者如果该方法是静态的,则它保存该方法类的监视器。
任何人都可以告诉我有什么区别:
答案 0 :(得分:4)
这意味着同步实例方法大致相当于:
public class FooClass {
public void foo() {
synchronized(this) {
...
}
}
}
而同步静态方法大致相当于:
public class FooClass {
public static void foo() {
synchronized(FooClass.class) {
...
}
}
}
因此,在实例方法的情况下,它将在FooClass
的实例上进行同步(并且在其他实例中调用foo
在其他实例上不会阻塞),而在静态方法案例,它在Class
对象本身上同步。
请注意,对于静态方法版本,它是包含方法的类,这很重要 - 即使该方法在名义上被称为“on”子类(例如SubFooClass.foo()
)方法仍然在声明它的类上获得一个监视器。
有关详细信息,请参阅JLS section 8.4.3.6。
答案 1 :(得分:0)
您可以在课程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
个对象都是单例,这就是它工作的原因)。
答案 2 :(得分:0)
在非静态方法上,锁定在实例上(this);即你的方法相当于:
public void method(){
synchronised(this){
//my code
}
}
在静态方法上,没有实例(你不能在静态方法中引用它)。因此锁定在实际的类对象(MyObject.class)上。
public static void method(){
synchronised(MyClass.class){
//my code
}
}
因此,使用1个同步方法和1个同步静态方法,两者可以同时执行,因为它们没有阻止它们并行运行,锁定在不同的对象上。