2010-10-06 27 views
4

我已经阅读了许多关于线程状态的文档,其中一些告诉我们有两种不同的状态:blocking(before同步)和等待(如果呼叫等待),其他人说只有一个状态:等待。此外,一些文档告诉你应该为每个wait()调用notify(),并且如果你不这样做,那么即使监视器被解锁,线程waiting()也永远不会被执行。是否有任何区别,如果线程正在等待监视器在同步块之前被释放,或者它调用wait()

回答

13

从你上一句我看你不完全明白​​和wait()/notify()之间的区别。

基本上,显示器有条件。这几乎是正交的概念。

  • 当线程输入一个​​块时,它获得一个锁。当线程离开该块时,它释放一个锁。只有一个线程可以在特定的监视器上锁定。

  • 当有锁的线程调用wait()时,它释放锁并开始等待其状态。当具有锁的线程调用notify()时,等待条件的其中一个线程(在notifyAll()的情况下的所有线程)变为符合执行条件(并且由于通知线程仍有它,因此开始等待获取锁)。

所以,等待获取锁(Thread.State.BLOCKED),并等待显示器的状态(Thread.State.WAITING)是不同的,独立的国家。

如果您看到Lock类 - 它实现与​​块(具有一些扩展)相同的同步原语,但在锁和条件之间提供了明显区别,此行为变得更加清晰。

+0

您的意思是说,notify()更改了显示器的状态?但是notifyAll()呢呢?这是否意味着监视器有一系列条件,每个线程都有一个条件。此外,线程是如何检查条件或锁定的,检查无限循环(while!monitor.lock)还是(while!monitor.condition [threadNum])?附:在这里我讲的是简单的监视器(对象),我不熟悉高层次的并发机制(是否有人使用它?) – dhblah 2010-10-06 13:47:36

+1

@gasan:Monitor的条件不是一般意义上的条件,它是一个同步原语,所以它不能改变。它只有一组等待它的线程。 'notifyAll()'和'notify()'的工作方式相同,但是对于等待条件的所有线程都是如此。 – axtavt 2010-10-06 14:06:04

1

Standard doc is here

当一个线程调用Object.wait 方法,它会释放此收购 监测和(如果我们调用超时 版本的wait方法或 TIMED_WAITING)状态投入WAITING。 现在,当该线程要么 通过notify()或通过notifyAll()呼叫上 相同的对象,则等待状态的线程端 和线程通知 开始试图恢复其已在 时间的获取的所有的 监视器等待电话。一次有 可能是几个线程试图 重新获得(或可能获得第一个 时间)他们的显示器。如果多于一个的线程 试图获得一个特定的对象,然后仅一个 螺纹(由JVM调度选择的) 的监视器 被授予监视和所有其他 线程被置于BLOCKED状态。

+0

你为什么认为'Object.wait'释放'所有'线程获得监视器?我认为它只发布'对象的锁。我读过某处但不记得在哪里。 – dhblah 2010-10-06 14:13:02

+0

@gasan我的意思是它释放所有获得的锁, – 2010-10-06 14:15:14

+0

是的,这正是我所要求的。你为什么要释放所有的锁?我认为它只释放这个特定的监视器锁。 – dhblah 2010-10-06 14:18:15

1

还有two different states BLOCKED和WAITING。

如果没有人通知(或中断)你是真的,那么关于永久等待的部分。

+0

非常感谢您的链接 – dhblah 2010-10-06 14:43:13

0

在Java的角度(Thread.State),有两种不同的状态:BLOCKED和WAITING。当一个线程在一个Object上同步时,它处于BLOCKED状态。线程执行等待后,它处于WAITING状态。

在Linux平台上,Java线程是OS本地线程。 BLOCKED和WAITING状态的OS线程状态是可中断的睡眠。使用ps进行检查时,BLOCKED和WAITING线程的状态为“S1 +”。

相关问题