Java 同步中不同监视对象的用途
有人能解释一下synchronized(this)和synchronized(c)之间的区别吗 我参考了各种各样的答案(,,,,),但无法理解并感到困惑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
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
本身不是线程,顺便说一句)。