【问题标题】:Can two threads execute the same synchronized block of code on the same object if they use different monitors?如果两个线程使用不同的监视器,它们可以在同一个对象上执行相同的同步代码块吗?
【发布时间】:2020-12-11 21:58:53
【问题描述】:

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

【问题讨论】:

    标签: java multithreading concurrency parallel-processing synchronized


    【解决方案1】:

    两个线程能否在同一实体上同时进入该部分 如果他们对监视器使用不同的对象?

    oracle tutorial可以阅读:

    每个对象都有一个与之关联的内在锁。 按照惯例, 需要对对象的独占和一致访问的线程 字段必须在访问之前获取对象的内在锁 它们,然后在完成它们后释放内在锁。一种 据说线程在它拥有的时间之间拥有内在锁 获取锁并释放锁。 只要一个线程拥有一个 内在锁,没有其他线程可以获取相同的锁。另一个 线程在尝试获取锁时会阻塞。

    这非正式地意味着可以同步使用任何Java Object。在单个对象实例上由子句 synchronized 包围的块将按顺序执行,由持有正在同步对象的锁的线程执行。 p>

    两个线程能否在同一实体上同时进入该部分 如果他们对监视器使用不同的对象?

    是的,只要每个线程使用不同的对象实例进行同步,多个线程就可以(并行)执行用synchronized 子句包裹的相同代码区域。

    也可以使用class 本身而不是它的实例进行同步:

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

    在这种情况下,所有在 SomeClass 类上使用子句 synchronized 的线程都必须相互同步

    也可以在方法上使用子句synchronized例如, public synchronized void method2());对于非静态方法,被同步的对象将是该方法所属的对象,而对于静态方法(例如, public static synchronized void method1()) 将是该方法所属的类本身。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-04
      • 1970-01-01
      • 2019-02-27
      • 1970-01-01
      • 2017-10-26
      • 2016-05-28
      • 1970-01-01
      相关资源
      最近更新 更多