服务器关闭时关闭选择器
Closing the Selector when server is shutting down
当我想关闭服务器时,我需要关闭阻塞线程的选择器。所以,我从主线程调用 selector.close()
,这有助于解锁 selector.select();
但是 selector 并没有像我猜的那样抛出 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<SelectionKey> readyKeys = selector.selectedKeys();
所以我想做两件事:
- 检测 selector 在 select() 解锁时是否关闭。 (可能吗?)
- 之后我想从
while(true)
中断并让线程停止。
我应该使用布尔标志、中断线程还是退出循环?
So I want to do two things:
Detect if the selector was closed when select() unblocks. (possible?)
After that I want to break from the while(true) and let the thread
stop.
如果您查看 Selector
中 close 方法的文档,您会看到它说 close
方法调用 wakeup
使当前 Selector
(如果等待)立即变为 return。
如果您查看 Selector
的文档,您会发现它有一个名为 isOpen.
的方法
public abstract boolean isOpen()
Tells whether or not this selector is open.
您需要做的就是在调用 selector.select()
后立即检查 selector.isOpen()
return 是否为假,如果 break
退出 while 循环 return是假的。您还应该将使用 selector
的任何代码移动到 try-catch
块中。不需要单独的 boolean
标志来实现这一点。这是您修改后的代码的外观:
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();
}
使用 isOpen
的优点是您现在可以确定您的服务器是正常关闭(未打印错误)还是在 activity 期间关闭19=](错误打印)
这里假设 whie(true)
循环是在 Thread
的 运行 方法中定义的。
当我想关闭服务器时,我需要关闭阻塞线程的选择器。所以,我从主线程调用 selector.close()
,这有助于解锁 selector.select();
但是 selector 并没有像我猜的那样抛出 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<SelectionKey> readyKeys = selector.selectedKeys();
所以我想做两件事:
- 检测 selector 在 select() 解锁时是否关闭。 (可能吗?)
- 之后我想从
while(true)
中断并让线程停止。
我应该使用布尔标志、中断线程还是退出循环?
So I want to do two things:
Detect if the selector was closed when select() unblocks. (possible?)
After that I want to break from the while(true) and let the thread stop.
如果您查看 Selector
中 close 方法的文档,您会看到它说 close
方法调用 wakeup
使当前 Selector
(如果等待)立即变为 return。
如果您查看 Selector
的文档,您会发现它有一个名为 isOpen.
public abstract boolean isOpen()
Tells whether or not this selector is open.
您需要做的就是在调用 selector.select()
后立即检查 selector.isOpen()
return 是否为假,如果 break
退出 while 循环 return是假的。您还应该将使用 selector
的任何代码移动到 try-catch
块中。不需要单独的 boolean
标志来实现这一点。这是您修改后的代码的外观:
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();
}
使用 isOpen
的优点是您现在可以确定您的服务器是正常关闭(未打印错误)还是在 activity 期间关闭19=](错误打印)
这里假设 whie(true)
循环是在 Thread
的 运行 方法中定义的。