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();
So I want to do two things:
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:
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.
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.
public abstract boolean isOpen()
Tells whether or not this selector is open.
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();
}
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)
The assumption here is that the whie(true)
loop is defined inside the run method of your Thread
.