如果两个线程使用不同的监视器,它们能在同一个对象上执行相同的同步代码块吗?

ktca8awb  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(376)

我对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”作为监视器。

wkftcu5l

wkftcu5l1#

如果两个线程对监视器使用不同的对象,是否可以在同一实体上同时进入该部分?
从oracle教程中可以看到:
每个对象都有一个与之相关联的内在锁。按照约定,需要独占和一致地访问对象字段的线程必须在访问对象字段之前获取对象的内部锁,然后在处理完这些字段后释放内部锁。线程在获取锁和释放锁之间拥有内在锁。只要一个线程拥有一个内在锁,其他线程就不能获得相同的锁。另一个线程将在尝试获取锁时阻塞。
这非正式地意味着可以使用任何java进行同步 Object . 用子句括起来的块 synchronized 在单个对象上,示例将按顺序执行,即由持有被同步对象的锁的线程执行。
如果两个线程对监视器使用不同的对象,是否可以在同一实体上同时进入该部分?
是的,多个线程可以(并行地)执行用 synchronized 子句,只要这些线程中的每个线程正在使用不同的对象示例进行同步。
也可以使用 class 它本身,而不是它的示例:

synchronized (SomeClass.class){
     System.out.println("Hello World");
 }

在这种情况下,所有使用该子句的线程 synchronized 在课堂上 SomeClass ,必须彼此同步。
也可以使用子句 synchronized 关于方法(例如。, public synchronized void method2() ); 对于非静态方法,被同步的对象将是该方法所属的对象,而对于静态方法(例如。, public static synchronized void method1() )将是该方法所属的类本身。

相关问题