Java中的某些方法会阻塞,直到它们可以执行某些操作,比如ServerSocket.accept()和InputStream.read(),但是它如何做到这一点对我来说并不容易找到.我能想到的最接近的事情是每次循环使用Thread.sleep()的while()循环,但是睡眠时间越长,阻塞响应越少,睡眠越短,发生的旋转越多.
我有两个问题:
各种标准功能(如上所述)如何阻止?原生代码?while()循环?别的什么?
我该如何实现阻止的方法?
小智.. 10
由于底层平台(即本机代码),您列出的操作会被阻止.
您可以使用Java Object.wait()
和Object.notify()
方法实现一个块; wait()
将阻塞调用线程,直到另一个线程调用notify()
同一个锁.
由于底层平台(即本机代码),您列出的操作会被阻止.
您可以使用Java Object.wait()
和Object.notify()
方法实现一个块; wait()
将阻塞调用线程,直到另一个线程调用notify()
同一个锁.
(1)的基本答案是"不要担心它 - 操作系统处理它".调用从输入流中读取的内容实际上是围绕操作系统调用的包装.在操作系统内部,我认为通常在这些情况下调用"阻塞"时,操作系统"知道"它正在等待来自磁盘控制器的硬件中断说这样的 - 和 - 这些请求的数据现在可用,并且它知道线程X是请求该数据的数据.因此它不会再次在线程X中进行调度,直到它收到该中断(或中断说"有错误"等).(然后,线程调度算法的一部分就是在等待的数据变得可用时为等待线程提供某种临时"提升".
在(2)中,我建议更多地思考"我怎么做可能碰巧阻止的事物X".我认为答案几乎没有"你想要做的事情"故意只是"阻止",而无论Thing X是什么,都可能有一个库方法/类会为你做.例如(链接包括我在这些主题上撰写的一些材料):
如果要在某个队列/提供者可用时获取下一个消息/作业,请查看阻塞队列
如果您需要通过对象上的"锁定"来控制对共享资源的访问,则在必要时等待锁可用,请考虑使用普通旧同步或显式锁定 ;
如果您想等待许多池化资源中的一个可用,请查看信号量
我会说原始等待/通知机制在很大程度上已经被Java 5并发API所弃用了.无论你做什么,自旋锁通常是最后的手段.