简体   繁体   English

同步中不同监控对象的用途

[英]Purpose of different monitor objects in synchronized

Could someone explain the difference between synchronized(this) and synchronized (c)?有人可以解释synchronized(this)和synchronized(c)之间的区别吗?

I refereed various answers( 1 , 2 , 3 , 4 , 5 ) but not able to understand and getting confused.我参考了各种答案( 1 , 2 , 3 , 4 , 5 )但无法理解并感到困惑。

public class Check {

    Consumer c = new Consumer(null);

    public void getSynch() {

        synchronized (this) {
            // doing some task
            System.out.println("Start");
        }

        synchronized (c) {
            // doing some task
            System.out.println("End");
        }

    }

}

I am able to understand the synchronized concept but not monitor object.我能够理解同步概念,但不能理解监视对象。 Please explain in a simple way.请用简单的方式解释。

synchronized always works on a monitor object (sometimes also called lock or semaphore). synchronized总是作用于监视器对象(有时也称为锁或信号量)。 Think of it as a token: when a thread enters a synchronized block it grads the token and other threads need to wait for the token to be returned.把它想象成一个令牌:当一个线程进入一个同步块时,它对令牌进行分级,其他线程需要等待令牌返回。 If you have multiple different monitor objects you basically have different tokens and thus synchronized blocks that operate on different monitors can run in parallel.如果你有多个不同的监视器对象,你基本上有不同的令牌,因此在不同监视器上运行的同步块可以并行运行。

There are many possibilities with this and many possible use cases.这个和许多可能的用例有很多可能性。 One could be that multiple instances of a class could run in parallel but need access to a shared and non-threadsafe resource.一个可能是一个类的多个实例可以并行运行,但需要访问共享和非线程安全的资源。 You then could use that resource or any other object that represents the "token" for that resource as the monitor object.然后,您可以使用该资源或任何其他代表该资源的“令牌”的对象作为监视器对象。

However, note that there's potential for deadlocks, eg in the following situation:但是,请注意存在死锁的可能性,例如在以下情况下:

Block 1:第 1 块:

synchronized(A) {
  //do something with A
  synchronized(B) {
    //do something with B
  }
}

Block 2:第 2 块:

synchronized(B) {
  //do something with B
  synchronized(A) {
    //do something with A
  }
}

Here both outer synchronized blocks could be entered in parallel because the two monitors A and B are available but then need to grab the other monitor and because they are now locked both threads would have to wait - class deadlock.这里两个外部同步块可以并行进入,因为两个监视器 A 和 B 可用,但随后需要获取另一个监视器,并且因为它们现在被锁定,两个线程将不得不等待 - 类死锁。

Also have a look at the dining philosophers problem which handles that topic as well (here the forks could be considered the monitor objects).还可以查看也处理该主题的哲学家进餐问题(此处可以将叉子视为监视器对象)。

Edit:编辑:

In your case (the code you've posted), multiple threads could try to call getSynch() on the same instance of Check .在您的情况下(您发布的代码),多个线程可能会尝试在Check的同一实例上调用getSynch() The first block synchronizes on the instance itself thus preventing multiple threads from entering that block if called on the same instance.第一个块在实例本身上同步,因此如果在同一实例上调用,则防止多个线程进入该块。

The second block synchronizes on c which is a different object and could change over time.第二个块在c上同步,这是一个不同的对象,可能会随着时间而改变。 Assume the first block ( synchronized(this) { ... } ) changes c to reference another instance of Consumer .假设第一个块( synchronized(this) { ... } )将c更改为引用Consumer另一个实例。 In that case you could have multiple threads run that block in parallel, eg if one entered the synchronized(c) block before the other thread reassigns c .在这种情况下,您可以让多个线程并行运行该块,例如,如果一个线程在另一个线程重新分配c之前进入了synchronized(c)块。

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

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