Java 同步中不同监视对象的用途

Java 同步中不同监视对象的用途,java,Java,有人能解释一下synchronized(this)和synchronized(c)之间的区别吗 我参考了各种各样的答案(,,,,),但无法理解并感到困惑 public class Check { Consumer c = new Consumer(null); public void getSynch() { synchronized (this) { // doing some task System.out

有人能解释一下synchronized(this)和synchronized(c)之间的区别吗

我参考了各种各样的答案(,,,,),但无法理解并感到困惑

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");
        }

    }

}

我能够理解同步概念,但不能理解监视对象。请简单解释。

同步
始终在监视器对象上工作(有时也称为锁或信号量)。将其视为令牌:当线程进入同步块时,它会对令牌进行分级,其他线程需要等待令牌返回。如果有多个不同的监视器对象,则基本上有不同的令牌,因此在不同监视器上运行的同步块可以并行运行

这有许多可能性,也有许多可能的用例。一种可能是一个类的多个实例可以并行运行,但需要访问共享的非线程安全资源。然后,您可以使用该资源或表示该资源的“令牌”的任何其他对象作为监视对象

但是,请注意,可能会出现死锁,例如在以下情况下:

第1区:

synchronized(A) {
  //do something with A
  synchronized(B) {
    //do something with B
  }
}
第2区:

synchronized(B) {
  //do something with B
  synchronized(A) {
    //do something with A
  }
}
在这里,两个外部同步块可以并行输入,因为两个监视器A和B都可用,但随后需要抓取另一个监视器,并且因为它们现在被锁定,所以两个线程都必须等待类死锁

还可以查看处理该主题的方法(在这里,fork可以被视为监视器对象)

编辑:

在您的情况下(您发布的代码),多个线程可以尝试在同一个
Check
实例上调用
getSynch()
。第一个块在实例本身上同步,从而防止在同一实例上调用时多个线程进入该块


第二个块在
c
上同步,这是一个不同的对象,可能会随时间而改变。假设第一个块(
synchronized(this){…}
)更改为
c
,以引用
消费者的另一个实例。在这种情况下,您可以让多个线程并行运行该块,例如,如果一个线程在另一个线程重新分配
c
之前输入
synchronized(c)
块,那么
这个
c
是两个不同的对象。这里的参数“this”是什么?当前线程(检查)完成后,只有检查线程的实例应单独等待?
这意味着
检查的当前实例将用作监视器。理论上,多个线程可以在同一个实例上调用
getSynch()
Check
本身不是线程,顺便说一句)。