服务器关闭时关闭选择器 [英] Closing the Selector when server is shutting down

查看:100
本文介绍了服务器关闭时关闭选择器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我想关闭服务器时,我需要关闭阻塞线程的选择器.因此,我从主线程调用了selector.close(),这有助于取消阻止selector.select();,但是选择器不会抛出ClosedSelectorException异常,就像我猜想的那样:

When I want to close the server, I will need to close Selector which is blocking the Thread. So, I call selector.close() from the main thread which helps to unblock selector.select(); But the selector doesn't throw ClosedSelectorException exception as it was supposed to I guess:

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();

    }

    // ...

但是它会在以后的行中引发异常:

But rather it throws the exception at the later lines:

Set<SelectionKey> readyKeys = selector.selectedKeys();

所以我想做两件事:

  • 检测在select()解除阻止时关闭选择器的情况. (可能吗?)
  • 之后,我想从while(true)中断并让线程停止.
  • 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.

我应该使用布尔标志,中断线程还是中断循环?

And should I use a boolean flag, interrupt the thread, or break from loop?

推荐答案

所以我想做两件事:

So I want to do two things:

检测在select()解除阻止时关闭选择器的情况. (可能吗?)

Detect if the selector was closed when select() unblocks. (possible?)

之后,我想从while(true)中断并让线程 停止.

After that I want to break from the while(true) and let the thread stop.

如果您查看Selector中的rel ="nofollow noreferrer">关闭方法,您会看到它说close方法调用wakeup,这将使当前的Selector(如果正在等待)立即返回. 如果查看Selector的文档,您会发现它具有一种称为

If you take a look at the docs for the close method in Selector, you will see that it says that the close method calls wakeup which will make the current Selector (if waiting) to return immediately. If you take a look at the docs for Selector,, you will see that it has a method called isOpen.

公共抽象布尔isOpen()

public abstract boolean isOpen()

告诉此选择器是否打开.

Tells whether or not this selector is open.

您需要做的只是检查selector.isOpen()在调用selector.select()之后是否立即返回false,如果break返回false,则只需在break循环之外进行检查.您还应该在try-catch块内移动所有使用selector的代码.不需要单独的boolean标志来实现此目的.这就是修改后的代码的外观:

All you need to do is to check if selector.isOpen() returns false immediately after you call selector.select() and simply break out of your while loop if it returns false. You should also move any code that uses the selector inside the try-catch block. There is no need to have a separate boolean flag to achieve this. This is how your modified code should look :

    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的优势在于,您现在将能够确定服务器是正常关闭(无错误打印)还是在selector上的某些活动之间关闭(有错误打印)

The advantage of using isOpen is that you will now be able to identify whether your server was shutdown gracefully (no error printed) or it was shutdown in between some activity on the selector (error printed)

这里的假设是whie(true)循环是在Thread的run方法中定义的.

The assumption here is that the whie(true) loop is defined inside the run method of your Thread.

这篇关于服务器关闭时关闭选择器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆