您的浏览器过于古老 & 陈旧。为了更好的访问体验, 请 升级你的浏览器
Ready 发布于2013年08月23日 08:19

原创 Java nio入门教程详解(三十五)

1119 次浏览 读完需要≈ 5 分钟

内容目录

4.3.2 停止选择过程

Selector的API中的最后一个方法,wakeup(),提供了使线程从被阻塞的select()方法中优雅地退出的能力:

public abstract class Selector {
	// 这里仅列出部分API
	public abstract void wakeup();
}

有三种方式可以唤醒在select()方法中睡眠的线程:

调用wakeup()
调用 Selector对象的 wakeup()方法将使得选择器上的第一个还没有返回的选择操作立即返回。如果当前没有在进行中的选择,那么下一次对 select()方法的一种形式的调用将立即返回。后续的选择操作将正常进行。在选择操作之间多次调用 wakeup()方法与调用它一次没有什么不同。

有时这种延迟的唤醒行为并不是您想要的。您可能只想唤醒一个睡眠中的线程,而使得后续的选择继续正常地进行。您可以通过在调用wakeup()方法后调用selectNow()方法来绕过这个问题。尽管如此,如果您将您的代码构造为合理地关注于返回值和执行选择集合,那么即使下一个select()方法的调用在没有通道就绪时就立即返回,也应该不会有什么不同。不管怎么说,您应该为可能发生的事件做好准备。

调用 close()
如果选择器的 close()方法被调用,那么任何一个在选择操作中阻塞的线程都将被唤醒,就像 wakeup()方法被调用了一样。与选择器相关的通道将被注销,而键将被取消。
调用 interrupt()
如果睡眠中的线程的 interrupt()方法被调用,它的返回状态将被设置。如果被唤醒的线程之后将试图在通道上执行I/O操作,通道将立即关闭,然后线程将捕捉到一个异常。这是由于在第三章中已经探讨过的通道的中断语义。使用 wakeup()方法将会优雅地将一个在 select()方法中睡眠的线程唤醒。如果您想让一个睡眠的线程在直接中断之后继续执行,需要执行一些步骤来清理中断状态(参见 Thread.interrupted()的相关文档)。

Selector对象将捕捉InterruptedException异常并调用wakeup()方法。

请注意这些方法中的任意一个都不会关闭任何一个相关的通道。中断一个选择器与中断一个通道是不一样的(参见 3.3 节)。选择器不会改变任意一个相关的通道,它只会检查它们的状态。当一个在select()方法中睡眠的线程中断时,对于通道的状态而言,是不会产生歧义的。

Java nio入门教程详解(三十六)

  • CodePlayer技术交流群1
  • CodePlayer技术交流群2

0 条评论

撰写评论