Java 服务器关闭时关闭选择器
当我想关闭服务器时,我需要关闭阻塞线程的选择器。因此,我从主线程调用Java 服务器关闭时关闭选择器,java,multithreading,sockets,selector,nio,Java,Multithreading,Sockets,Selector,Nio,当我想关闭服务器时,我需要关闭阻塞线程的选择器。因此,我从主线程调用selector.close(),这有助于解除阻止selector.select()但是选择器不会像我猜想的那样抛出ClosedSelectorException异常: while (true) { try { // Blocks until a 'socket' is ready registered with selector is ready. selector.select()
selector.close()
,这有助于解除阻止selector.select()代码>但是选择器不会像我猜想的那样抛出ClosedSelectorException
异常:
while (true) {
try {
// Blocks until a 'socket' is ready registered with selector is ready.
selector.select();
}
catch (ClosedSelectorException ex) {
// Never reached?
ex.printStackTrace();
}
catch (IOException ex) {
// Never reached?
ex.printStackTrace();
}
// ...
但它会在后面几行抛出异常:
Set readyKeys=selector.selectedKeys()代码>
所以我想做两件事:
- 在select()解除阻止时检测选择器是否已关闭。(可能吗?)
- 之后,我想从
中断while(true)
,让线程停止
我应该使用布尔标志、中断线程还是中断循环
所以我想做两件事:
在select()解除阻止时检测选择器是否已关闭。(可能吗?)
在那之后,我想从while(true)中断,让线程
停下来
如果您查看选择器
中方法的文档,就会发现关闭
方法调用唤醒
,这将使当前的选择器
(如果等待)立即返回。
如果您查看选择器的文档,您将看到它有一个名为的方法
公共抽象布尔等参元()
指示此选择器是否打开
您只需在调用selector.select()
后立即检查selector.isOpen()
是否返回false,如果返回false,只需将中断退出while循环即可。您还应该在try catch
块内移动使用选择器的任何代码。不需要使用单独的布尔
标志来实现这一点。以下是修改后的代码的外观:
try {
// Blocks until a 'socket' is ready registered with selector is ready.
selector.select();
if(!selector.isOpen()) {
break;//graceful exit since selector was not in use anyway
}
Set<SelectionKey> readyKeys = selector.selectedKeys();
// ...
} catch (ClosedSelectorException ex) {
// selector was closed while being used
ex.printStackTrace();
} catch (IOException ex) {
// some other exception
ex.printStackTrace();
}
试试看{
//阻止,直到“套接字”准备就绪并注册到选择器准备就绪。
selector.select();
如果(!selector.isOpen()){
break;//退出,因为选择器未被使用
}
设置readyKeys=selector.selectedKeys();
// ...
}捕获(关闭选择例外){
//选择器在使用时已关闭
例如printStackTrace();
}捕获(IOEX异常){
//还有一些例外
例如printStackTrace();
}
使用isOpen
的优点是,您现在可以确定服务器是正常关闭(未打印错误),还是在选择器上的某些活动之间关闭(打印错误)
这里的假设是whie(true)
循环是在线程的run方法中定义的
您是否尝试过从异常处理程序返回?循环将继续到下一个方法,该方法将抛出一个未处理的ClosedSelectorException,因为选择器已经关闭。只需将..
放入try
块中。@EJP不会导致程序打印出异常日志吗?不,它将导致捕获中出现“从未到达”(已关闭的选民)
块,您可以在其中做任何您想做的事情。@EJP我想说的是,如果在我们继续做任何工作之前关闭了选择器,那么什么都不应该发生,线程应该结束。如果在我们继续做一些工作之后关闭选择器,这是一个例外情况。前者实际上不是例外我们不应该使用副作用(使用关闭的选择器执行操作时发生异常)作为退出线程的手段。这样更好。一方面,您可以通知“选择器正常关闭”和“选择器异常关闭”但是我不确定是否会出现closedselectrorexception
。你在哪里和什么时候关闭selector
?。你能保证其他使用你的代码的开发人员不会在selector
做一些工作时意外地关闭它吗?好的,我现在明白了。选择器可以在执行isOpen
后关闭。此时异常将非常有用。我从主线程关闭它以停止服务器线程。准确地说。很高兴您终于理解了我所说的:)