简体   繁体   English

持有监视器的Java线程

[英]Java threads holding a monitor

I was reading about java threads and happened to read this blog. 我在阅读有关Java线程的文章,碰巧阅读了博客。 In the blog I came across a statement: 在博客中,我遇到了一个声明:

During the execution of a synchronized method, the thread holds the monitor for that method's object, or if the method is static, it holds the monitor for that method's class. 在执行同步方法期间,线程为该方法的对象保留监视器,或者,如果该方法为静态,则为该方法的类保留监视器。

Can anyone please tell me what is the difference between: 谁能告诉我有什么区别:

  • a thread is holding the monitor for methods object 线程持有方法对象的监视器
  • a thread is holding the monitor for methods class 线程持有方法类的监视器

It means that a synchronized instance method is broadly equivalent to: 这意味着同步实例方法大致等效于:

public class FooClass {
    public void foo() {
        synchronized(this) {
            ...
        }
    }
}

Whereas a synchronized static method is broadly equivalent to: 而同步静态方法大致等效于:

public class FooClass {
    public static void foo() {
        synchronized(FooClass.class) {
            ...
        }
    }
}

So in the instance method case it will synchronize on an instance of FooClass (and calls to foo in other threads on other instances will not block), whereas in the static method case it synchronizes on the Class object itself. 因此,在实例方法的情况下,它将在FooClass的实例上同步(并且在其他实例上的其他线程中 foo调用将不会阻塞),而在静态方法的情况下,它将在Class对象本身上进行同步。

Note that for the static method version, it's the class containing the method which is important - even if the method is notionally called "on" a subclass (eg SubFooClass.foo() ) the method still obtains a monitor on the class in which it's declared. 请注意,对于静态方法版本,重要的是包含该方法 -即使在概念上将该方法“称为”子类(例如SubFooClass.foo() ),该方法仍会在该类所在的类上获取监视器宣布。

See JLS section 8.4.3.6 for more details. 有关更多详细信息,请参见JLS 8.4.3.6节

You can rougly translate, in a class Foo , say: 您可以在Foo类中粗暴地翻译说:

public synchronized foo()
{
    doSomething();
}

to: 至:

public foo()
{
    synchronized(this) {
        doSomething();
    }
}

Whereas: 鉴于:

public static synchronized foo()
{
    doSomething();
}

translates (roughly) to: 大致翻译为:

public static foo()
{
    synchronized(Foo.class) {
        doSomething();
    }
}

In the first case, you synchronize against the current instance of Foo ( this ). 在第一种情况下,您将与Foo的当前实例( this )进行同步。 In the second case, you synchronize against the Class object (all Class objects are singletons, this is why it works). 在第二种情况下,您将与Class对象进行同步(所有Class对象都是单例,这就是它起作用的原因)。

on a non static method, the lock is on the instance (this); 在非静态方法上,锁在实例上(此); ie your method is equivalent to: 即您的方法等效于:

public void method(){
    synchronised(this){
        //my code
    }
}

on a static method, there is no instance (you can't reference this in a static method). 在静态方法上,没有实例(您不能在静态方法中引用此实例)。 So the lock is on the actual class object (MyObject.class). 因此,锁位于实际的类对象(MyObject.class)上。

public static void method(){
    synchronised(MyClass.class){
        //my code
    }
}

Hence with 1 synchronised methods and 1 synchronised static method, the two can execute at the same time as they nothing prevents them from running in parallel, the locks being on different objects. 因此,使用1个同步方法和1个静态同步方法,这两个函数可以同时执行,因为它们什么也不能阻止它们并行运行,因为锁位于不同的对象上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM