Java NIO Selector
In this post, we will explore feature and the basic understanding of Java NIO Selector API. The selector is an NIO component with an ability to monitor or examine multiple channels and determines which is ready for the IO operation (read or write).
One of the benefits of this is to use single thread to manage multiple channels which in simple terms is “multiple network connections”
1. Use of NIO Selector
If you are familiar with threads, you must be aware that switching between thread is an expensive process as it involves underlying operating system, also thread means a new process which eventually will consume some memory. (With new OS, switching threads is not a big issue)
With Java NIO Selector, you can use a single thread to manage multiple channels, in other words, you are not creating multiple threads to manage multiple channels.
2. Selector Configurations
The selector is part of the java.nio package. We can register multiple channels with Selector, once registration is done, Selector API will inform us if any NIO activity happens with these registered channels.
3. Creating Selector
A new selector can be created by using open method of Selector class.JDK internally call system-wide default SelectorProvider.
Selector selector = Selector.open();
3. Register Channels with Selector
For Selector to monitor different channels, we need to register these channels with Selector.To register, use register method of the selectable channel.
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("https://javadevjournal.com",80));
socketChannel.configureBlocking(false);
SelectionKey key= socketChannel.register(selector, SelectionKey.OP_READ);
with configureBlocking(false), we are setting it in non-blocking mode. While registering the first parameter passed to register method is the selector.
The second parameter is called “interest set”, it indicates at what even selector should notify us. SelectionKey provides following 4 options as “interest set”
Operation Name | Description |
OP_READ | When server is ready to read from Channel |
OP_WRITE | Ready to write |
OP_CONNECT | When the client is trying to connect. |
OP_ACCEPT | When the server accepts client connection request |
Register method will return SelectionKey represent channel register with the selector.
4. Selection Key
Channel registration with the selector return SelectionKey object SelectionKey
is a representation of the SeletableChannel
and contains few of the interesting elements, in order to utilise selector efficiently, a basic understanding of these elements is desired.
4.1 Interest Set
Interest set contains information about the event we are interested. It is an integer value. We can use interestOps()
method to get set which is valid for current Channel.
We can use int value returned by interestOps
method along with SelectionKey class to determine correct interest set.
int interestSet= key.interestOps();
4.2 Ready Set
Ready set defined a set of event that selected channel is ready for, the Ready set is also represented by an integer value.Use readyOps()
method to get information about the Ready Set.
int readySet= key.readyOps();
Alternatively, you can use SelectionKey’s utility method to get these values.
key.isAcceptable();
key.isConnectable();
Keep in mind that these methods will return a boolean value and not an integer.
4.2 Channel and Selector
Use SelectionKey class to get information about the associated Channel and Selector
key.channel();
key.selector();
5. Channel Selection Process
As of now we have done following work
- Create Selector.
- Create Desired Channel.
- Register channel with the selector.
Once we register multiple channels with the selector, use the select method to get the interested channel (e.g If we want Channel ready for reading, we will get channel ready for reading).
selector.select();
Above method will work in blocking mode, It returns only after at least one channel is selected.Returned int value represents a number of channels ready for the operation.
As I said, select()
the method will give us a hint as how many channels are ready for the operation, we can access all these ready channels by using selectedKeys() method.
Set<SelectionKey> readyToUseChannel= selector.selectedKeys();
You can iterate over the set to get information about the ready channels and can use the desired channel to perform required information (Read, Write operation etc.).
Set<SelectionKey> readyToUseChannel= selector.selectedKeys();
for(SelectionKey selectionKey : readyToUseChannel){
if(selectionKey.isAcceptable()){
// connection accepted
}
else if(selectionKey.isReadable()){
//channel ready to read
}
}
References
Comments are closed.