Selector for JAVA-5NIO, java-5nioselector

Source: Internet
Author: User

Selector for JAVA-5NIO, java-5nioselector

Reprint: Concurrent Programming Network: ifeve.com NIO tutorial

Selector is a component that can detect one or more NIO channels in Java NIO and know whether the channel is prepared for read/write events. In this way, a single thread can manage multiple channels to manage multiple network connections.

1. Why Selector?

The advantage of using a single thread to process multiple Channels is that fewer threads are needed to process Channels. In fact, you can use only one thread to process all the channels. For the operating system, context switching between threads is costly, and each thread occupies some system resources (such as memory ). Therefore, the fewer threads used, the better.

However, remember that the performance of modern operating systems and CPUs is getting better and better in terms of multitasking, so the overhead of multithreading becomes smaller and smaller over time. In fact, if a CPU has multiple kernels, the CPU capability may be wasted if no multi-task is used. In any case, the discussion about that design should be put in another article. Here, it is sufficient to know that Selector can process multiple channels.

Ii. Create Selector

Create a Selector by calling the Selector. open () method, as shown below:

Selector selector = Selector.open();
3. Register a channel with Selector

To use the Channel and Selector together, you must register the channel to the selector. Use the SelectableChannel. register () method as follows:

channel.configureBlocking(false);SelectionKey key = channel.register(selector,Selectionkey.OP_READ);

When used with Selector, the Channel must be in non-blocking mode. This means that FileChannel and Selector cannot be used together, because FileChannel cannot be switched to non-blocking mode. All socket channels are supported.

Note the second parameter of the register () method. This is an "interest set", which means what events are interested in listening to channels through Selector. You can listen to four different types of events:

The channel triggers an event, which means the event is ready. Therefore, a channel successfully connects to another server and is called "connection ready ". A server socket channel is ready to receive incoming connections ". A channel with readable data can be said to be "Read-ready ". The channel waiting for Data Writing can be said to be "ready to write ".

These four events are represented by four constants of SelectionKey:

If you are interested in more than one event, you can use the bitwise OR operator to connect constants as follows:

int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE;

The interest set will be further mentioned below.

Iv. SelectionKey

In the previous section, when registering a Channel with Selector, the register () method returns a SelectionKey object. This object contains some attributes you are interested in:

  • Interest set
  • Ready Set
  • Channel
  • Selector
  • Additional object (optional)

I will describe these attributes below.

Interest set

As described in registering a channel with Selector, the interest collection is the collection of events you are interested in. You can use SelectionKey to read and write the interest set, as shown in the following code:

int interestSet = selectionKey.interestOps();boolean isInterestedInAccept  = (interestSet & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT;

We can see that using bitwise AND to operate the interest set and the given SelectionKey constant can determine whether a certain event is in the interest set.

Ready Set

The ready set is a set of operations that are ready for the channel. After a Selection, you will first access this ready set. Selection will be explained in the next section. You can access the ready set as follows:

int readySet = selectionKey.readyOps();

You can use methods like interest collection to detect events or operations in the channel. However, you can also use the following four methods to return a boolean type:

selectionKey.isAcceptable();selectionKey.isConnectable();selectionKey.isReadable();selectionKey.isWritable();
Channel + Selector

It is easy to access the Channel and Selector from SelectionKey. As follows:

Channel  channel  = selectionKey.channel();Selector selector = selectionKey.selector();
Additional object

You can attach an object or more information to the SelectionKey to easily identify a given channel. For example, you can append the Buffer used with the channel or an object that contains the aggregated data. The usage is as follows:

selectionKey.attach(theObject);Object attachedObj = selectionKey.attachment();

You can also append an object when registering a Channel with Selector using the register () method. For example:

SelectionKey key = channel.register(selector, SelectionKey.OP_READ, theObject);
5. Select a channel through Selector

Once one or more channels are registered with Selector, several overloaded select () methods can be called. These methods return the channels that are ready for the events you are interested in (such as connection, acceptance, read, or write. In other words, if you are interested in the "Read-ready" channel, the select () method will return those channels with read events ready.

The select () method is as follows:

  • Int select ()
  • Int select (long timeout)
  • Int selectNow ()

select()Blocking to at least one channel is ready for the event you registered.

select(long timeout)Like select (), except for the maximum blocking timeout Millisecond (parameter ).

selectNow()No blocking, No matter what channel is ready, return immediately (Note: This method performs a non-blocking selection operation. If no channel becomes selectable since the previous selection operation, this method returns zero directly.).

The int value returned by the select () method indicates how many channels are ready. That is, how many channels have become ready since the select () method was called last time. If the select () method is called, 1 is returned because one channel is ready. If the select () method is called again, 1 is returned if the other channel is ready. If no operation is performed on the first ready channel, there are now two ready channels, but only one channel is ready between each select () method call.

SelectedKeys ()

Once the select () method is called and the return value indicates that one or more channels are ready, you can call the selectedKeys () method of selector, access the ready channel in selected key set. As follows:

Set selectedKeys = selector.selectedKeys();

When a Channel is registered like a Selector, the Channel. register () method returns a SelectionKey object. This object represents the channel registered to this Selector. You can access these objects through the selectedKeySet () method of SelectionKey.

/*** Selector */@ Test public void test3 () throws IOException {Selector selector = Selector. open (); SocketChannel socketChannel = SocketChannel. open (); socketChannel. configureBlocking (false); // register this channel SelectionKey register = socketChannel with selector. register (selector, SelectionKey. OP_READ); // in this example, I = SelectionKey. OP_READ int I = register. interestOps (); // you can determine the event boolean B = (I & SelectionKey. OP_READ) = SelectionKey. OP_READ; // Of course, you can use the isXX Method to Determine boolean readable = register. isReadable (); // return the number of prepared selectionkeys. If the value is greater than 0, the following method can be called: int select = selector. select ();/*** if select> 0, which is usually a while (true) loop * // The prepared SelectionKey is saved in this example, that is, the channel // note that the SelectionKey must be manually removed, and the Set <SelectionKey> selectionKeys = selector will not be automatically removed. selectedKeys (); Iterator keyIterator = selectionKeys. iterator (); while (keyIterator. hasNext () {SelectionKey key = (SelectionKey) keyIterator. next (); // obtain the channel SelectableChannel channel = key. channel (); // obtain selector Selector selector1 = key. selector (); if (key. isAcceptable () {// a connection was accepted by a ServerSocketChannel .} else if (key. isConnectable () {// a connection was established with a remote server .} else if (key. isReadable () {// a channel is ready for reading} else if (key. isWritable () {// a channel is ready for writing} // remove keyIterator. remove ();} // disable selector. close ();}

 

Note the keyIterator. remove () call at the end of each iteration. Selector does not remove the SelectionKey instance from the selected key set. You must remove the channel after processing. The next time the channel is ready, the Selector puts it in the selected key set again.

The channel returned by the SelectionKey. channel () method needs to be transformed into the type you want to process, such as ServerSocketChannel or SocketChannel.

WakeUp ()

After a thread calls the select () method, it is blocked. Even if no channel is ready, there is a way to get it back from the select () method. You only need to have other threads call the Selector. wakeup () method on the object where the first thread calls the select () method. The thread blocking on the select () method will immediately return.

If other threads call the wakeup () method but no threads are blocked on the select () method, the next thread that calls the select () method will immediately "wake up (wake up) ".

Close ()

After using Selector, calling its close () method will disable the Selector and invalidate all SelectionKey instances registered to the Selector. The channel itself does not close.

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.