我对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();
}
如果我正确理解监视器,那么是的,所有线程都可以同时进入synchronized块,因为每个监视器充当完全不同的mutex,并且没有一个线程知道该块中的其他线程。
很难找到关于这一点的文档,因为教程似乎只使用“this”作为监视器。
1条答案
按热度按时间wkftcu5l1#
如果两个线程对监视器使用不同的对象,是否可以在同一实体上同时进入该部分?
从oracle教程中可以看到:
每个对象都有一个与之相关联的内在锁。按照约定,需要独占和一致地访问对象字段的线程必须在访问对象字段之前获取对象的内部锁,然后在处理完这些字段后释放内部锁。线程在获取锁和释放锁之间拥有内在锁。只要一个线程拥有一个内在锁,其他线程就不能获得相同的锁。另一个线程将在尝试获取锁时阻塞。
这非正式地意味着可以使用任何java进行同步
Object
. 用子句括起来的块synchronized
在单个对象上,示例将按顺序执行,即由持有被同步对象的锁的线程执行。如果两个线程对监视器使用不同的对象,是否可以在同一实体上同时进入该部分?
是的,多个线程可以(并行地)执行用
synchronized
子句,只要这些线程中的每个线程正在使用不同的对象示例进行同步。也可以使用
class
它本身,而不是它的示例:在这种情况下,所有使用该子句的线程
synchronized
在课堂上SomeClass
,必须彼此同步。也可以使用子句
synchronized
关于方法(例如。,public synchronized void method2()
); 对于非静态方法,被同步的对象将是该方法所属的对象,而对于静态方法(例如。,public static synchronized void method1()
)将是该方法所属的类本身。