【问题标题】:Thread inherits lock from spawning thread线程从生成线程继承锁
【发布时间】:2014-07-17 16:47:59
【问题描述】:

当生成的线程尝试获取自己的锁时,以下代码没有阻塞。

衍生线程是否从衍生线程继承锁?

代码如下:

public class A {

    public void methodA() {
        public class SpawnedThread extends Thread {
            public void run() {
                synchronized(this) {
                ...
            }
       };

       SpawnedThread spawnedThread= new SpawnedThread ();
       synchronized(spawnedThread) {
            spawnedThread.start();
            spawnedThread.join();
      };
      ...
   }
}

【问题讨论】:

    标签: java multithreading join wait synchronized


    【解决方案1】:

    线程不会从其他线程继承锁,这里发生了其他事情。

    在您的示例中,运行 methodA 的线程必须先锁定 spawnedThread,然后才能进入同步块。

    然后当 spawnedThread 运行时,它必须获取自身的锁才能进入 run 方法中的同步块。

    所以 methodA 线程拥有锁,而 spawnedThread 正试图获得相同的锁。但它不会死锁,因为 Thread.join 在放弃锁的地方执行等待,请参阅api documentation for Thread.join

    此实现使用以 this.isAlive 为条件的 this.wait 调用循环。当线程终止时,将调用 this.notifyAll 方法。建议应用程序不要在 Thread 实例上使用 wait、notify 或 notifyAll。

    没有超时值的 Thread.join 版本会锁定它正在加入的线程,放弃它,然后进入休眠状态。在发生以下情况之一之前它不会唤醒:

    1) 正在加入的线程完成(发送唤醒等待线程的通知)

    2) 加入线程被中断(意味着在它上面调用了中断,这在本例中不会发生)

    3) 加入线程自行唤醒(“虚假唤醒”,这种情况很少见,是竞争条件的结果)

    我不清楚您将如何更改锁以在此处出现死锁,如您在评论中描述的那样,如果您想得到答案,请将该版本的代码添加到您的问题中。

    【讨论】:

      【解决方案2】:

      衍生线程是否从衍生线程继承锁?

      不,您也没有在衍生线程中持有任何锁以供衍生线程继承。

      您可以尝试使用Lock 执行此操作,但如果您尝试,它将引发 IllegalMonitorStateException。

      “同步(spawnedThread){ spawnedThread.start(); };”在实例化 spawnedThread 之后。

      一旦你退出这个块,被生成的线程就可以获得锁。如果您想查看死锁,请将 join() 移到同步块内。

      【讨论】:

      • 我刚试过。它没有陷入僵局。但是,如果我在 spawnedThread 本身以外的对象上进行同步,则会出现死锁。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-26
      • 2013-12-28
      相关资源
      最近更新 更多