java - 如果两个线程使用不同的监视器,它们可以在同一个对象上执行相同的同步代码块吗?
问题描述
我对 Java 并发很陌生,我正在尝试更好地理解监视器。
假设我有一个对象,其方法采用某种引用参数并将该参数用作同步块中的监视器:
class Entity() {
public void myMethod(Object monitor) {
synchronized(monitor) {
// critical stuff
}
}
}
如果两个线程使用不同的对象作为监视器,是否可以同时进入同一实体上的该部分?
final Entity myEntity = new Entity();
for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
// Can these all run concurrently?
myEntity.myMethod(new Object());
}
}.start();
}
如果我正确理解了监视器,那么是的,所有线程都可以同时进入同步块,因为每个监视器都充当完全不同的互斥锁,并且没有一个线程知道该块中的其他线程。
很难找到这方面的文档,因为教程似乎大多只是使用“this”作为监视器。
解决方案
如果两个线程对监视器使用不同的对象,是否可以同时进入同一实体上的该部分?
从oracle 教程中可以阅读:
每个对象都有一个与之关联的内在锁。按照惯例,需要对对象字段进行排他和一致访问的线程必须在访问对象之前获取对象的内在锁,然后在完成访问时释放内在锁。在获得锁和释放锁之间,线程被称为拥有内在锁。只要一个线程拥有一个内在锁,其他线程就不能获得相同的锁。另一个线程在尝试获取锁时会阻塞。
这非正式地意味着可以使用任何 Java进行同步Object
。由单个对象实例上的子句包围的块synchronized
将按顺序执行,即由持有正在同步对象的锁的线程执行。
如果两个线程对监视器使用不同的对象,是否可以同时进入同一实体上的该部分?
synchronized
是的,只要每个线程都使用不同的对象实例进行同步,多个线程就可以(并行)执行用子句包裹的相同代码区域。
也可以使用class
自身而不是其实例进行同步:
synchronized (SomeClass.class){
System.out.println("Hello World");
}
在这种情况下,所有使用synchronized
class子句的线程SomeClass
都必须相互同步。
也可以synchronized
在方法上使用子句(例如, public synchronized void method2()
);对于非静态方法,被同步的对象将是该方法所属的对象,而对于静态方法(例如, public static synchronized void method1()
)将是该方法所属的类本身。
推荐阅读
- flutter - 如何在我的颤振项目中永久更新数据?
- python - 从数据框中减去特定列的每一行并添加到列表 -python
- ssis - 如何使用 int 数据类型定义 SSIS For Loop Eval 表达式?
- github - GitHub“新身份验证令牌格式的通知”
- flutter - Chrome 上的 Flutter Web
- java - 未提及外键的架构的 ER 图
- python - 在 Pandas DataFrame 上循环
- wait - 有没有办法让 Denodo 8 VDP 调度程序作业 WAIT() 一段时间?
- mysql - 如何根据过程中的输入参数使用不同的 where 条件?
- flutter - 如何在flutter中使用transmission或flutter_transmission包?