[英]Can two threads execute the same synchronized block of code on the same object if they use different monitors?
我对 Java 并发很陌生,我正在努力更好地理解监视器。
假设我有一个 object,其方法采用某种引用参数并将该参数用作同步块中的监视器:
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 教程中可以阅读:
每个 object 都有一个与之关联的内在锁。 按照惯例,需要对对象字段进行排他和一致访问的线程必须在访问对象之前获取对象的内在锁,然后在完成访问时释放内在锁。 在获得锁和释放锁之间,线程被称为拥有内在锁。 只要一个线程拥有一个内在锁,其他线程就不能获得相同的锁。 另一个线程在尝试获取锁时会阻塞。
这非正式地意味着可以使用任何 Java Object
进行同步。 在单个 object 实例上由synchronized
子句包围的块将按顺序执行,即由持有正在同步的 object 锁的线程执行。
如果两个线程使用不同的对象作为监视器,是否可以同时进入同一实体上的该部分?
是的,只要每个线程使用不同的 object 实例进行同步,多个线程就可以(并行)执行使用synchronized
子句包装的相同代码区域。
也可以使用class
本身而不是其实例进行同步:
synchronized (SomeClass.class){
System.out.println("Hello World");
}
在这种情况下,使用 class SomeClass
上synchronized
子句的所有线程都必须相互同步。
也可以在方法上使用synchronized
子句(例如, public synchronized void method2()
); for non-static methods the object being synchronized will be the object to which that method belongs, whereas for static methods ( eg, public static synchronized void method1()
) will be class itself to which that method belongs.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.