Java信号量默认使用忙等待还是wait/notify机制?

5
作为这个问题的解答,我在Windows 7上使用JDK 6.0,并尝试使用信号量作为同步机制来解决我的同步问题。它完美地工作,但我正在尝试避免在我的问题中繁忙等待。
我只想询问Java文档并减少SO的麻烦,但文档是这样的:
Acquires the given number of permits from this semaphore,
 blocking until all are available, or the thread is interrupted.

Acquires the given number of permits, if they are available,
 and returns immediately, reducing the number of available permits
 by the given amount.

If insufficient permits are available then the current thread
 becomes disabled for thread scheduling purposes and lies dormant

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Semaphore.html#acquire(int)

这就是说,文档似乎暗示了两个答案。哪一个才是正确的?


大多数java.util.concurrent原语都依赖于基于park/unpark的java.util.concurrent.locks.AbstractQueuedSynchronizer,即没有忙碌自旋。 - bestsss
2个回答

1

我并不认为它暗示了忙等待。它明确说明线程是“禁用”的和休眠的。基本上,这很便宜:线程在等待获取信号量时不会消耗处理器时间。


但在上面一行,它说线程在等待时会阻塞,这似乎是矛盾的。 - Faqa
1
是的。阻塞<>忙等待。如果一个线程在信号量上调用“wait”,但“许可证”不足,则该调用不会返回,直到另一个线程发出足够的许可证以满足等待线程。正如Jon Skeet在上面发布的那样-线程在等待期间被阻塞,并且根本没有CPU。尝试一下-在空信号量上阻塞循环线程并检查CPU使用情况-它将为零。 - Martin James
@Faqa:正如Martin所说,阻塞不等同于忙等。 - Jon Skeet

0

根据这行代码,显然是使用了wait/notify:

如果没有足够的许可证可用,则当前线程将因线程调度目的而被禁用并处于休眠状态。

这意味着直到唤醒它的事件(可用的信号量许可)发生之前,线程不会被操作系统调度,此时线程将被通知继续执行。


这是关于编程的内容:它是park/unpark,而不是wait/notify,因为它们之间有区别:wait/notify需要同步(或争用),而park/unpark则不需要。 - bestsss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接