等待期间Java线程的状态是什么,无法获取锁定

时间:2016-04-26 21:23:26

标签: java multithreading concurrency

Java线程可以通过以下任一方式保存:

  1. 无法获得锁定。
  2. 由wait()方法持有。
  3. 上述两种场景在Java线程状态方面有什么区别?

    考虑以下简单代码:

       synchronized(object) {
           object.wait();
           System.out.println("Completed.");
       }
    

    如果两个线程(比如ThreadA和ThreadB)全部都保存在wait()方法中。当另一个线程调用notifyAll()时,ThreadA将从等待中恢复并获取对象的锁定并继续,例如。 ThreadB也将恢复但无法获取对象的锁定并保持直到ThreadA退出synchronized块。然后ThreadB获得锁定并继续。

    结果将是两个"已完成"印刷。

    在这个例子中,ThreadB必须有一段时间从"由wait()"因为它无法锁定对象而被关押#34;。

    我想知道它在Java内部是如何工作的。请帮忙。

2 个答案:

答案 0 :(得分:2)

查看Thread.State,更具体地说是WAITINGBLOCKED州。

如果您对内部实施感兴趣,可以使用LockSupport.park()LockSupport.unpark(Thread)实现这两项目标,而且实际上它们是如何在大多数地方实施的。

P.S。如果您感兴趣,以下是Windows (line 4946)Linux (line 5808)的OpenJDK park()实现,这里是wait()/notify()/notifyAll()实现(第1457行)。他们的评论非常好,只要给它一些时间,如果一眼看上去太复杂了。

答案 1 :(得分:2)

处于object.wait()状态和等待object监视器上的锁定之间的区别是object.wait()状态的线程释放了它所拥有的object的所有监视器,它将与系统中的所有线程竞争再次重新获取监视器。这使得wait()成为一种特殊的状态。

因此,在AB(主题A和主题B)处于等待状态的情况下,他们没有同步监视器object,它们已被暂停执行,直到其他线程调用object.notify()object.notifyAll()。当notifyAll()被调用时,JVM唤醒A状态中的所有线程(在这种情况下为Bobject.wait()),他们竞争获取当前synchronized的监视器1}}阻止。如果调用notify(),则JVM随机选择A或B.

这里需要注意的是,JVM没有通知任何特定的线程,这就是为什么每个等待的线程都必须在while(notify_condition_for_me)循环中等待,以验证等待条件是否有如果不是,它必须再次进入object.wait()状态。

所以正确的代码应该是

synchronized(object) {
   while(myResourceArrived) {//like URL data, JDBC data or something
       object.wait();
   }
   System.out.println("Completed.");
}

AB处于object.wait()状态时,他们已经释放了之前为object保留的所有监视器,因此在synchronized之外等待的任何其他线程{1}}阻止将立即通过获取object的已发布监视器来进入该区块。