Reactor mode and NiO

Source: Internet
Author: User

Currently, distributed computing Web services are prevalent, and the underlying layers of these network services are inseparable from socket operations. They all have a common structure:
1. Read Request
2. Decode request
3. Process Service
4. encode reply
5. Send reply

The classic network service is designed to process data in each thread:

However, when the user load increases, the performance will decrease very quickly. We need to find a new solution to ensure smooth data processing. Obviously, the event trigger mechanism is the best solution. when an event occurs, handler is triggered, then start data processing.

The reactor mode is similar to event processing in AWT:

Reactor mode participant

1. The reactor is responsible for responding to Io events. Once an event occurs, the broadcast is sent to the corresponding handler for processing. This is similar to the AWT thread
2. handler is responsible for non-blocking behaviors, similar to AWT actionlisteners. It is also responsible for binding handlers to Event Events, similar to AWT addactionlistener.


Java NiO provides a basic implementation mechanism for the reactor mode. When its selector finds that a channel has data, it will notify us through slectorkey. Here we implement event binding and handler binding.

Let's take a look at the reactor mode.Code:

Public class reactor implements runnable {

Final selector;
Final serversocketchannel serversocket;

Reactor (INT port) throws ioexception {
Selector = selector. open ();
Serversocket = serversocketchannel. open ();
Inetsocketaddress address = new inetsocketaddress (inetaddress. getlocalhost (), Port );
Serversocket. socket (). BIND (Address );

Serversocket. configureblocking (false );
// Register the channel with Selector
Selectionkey Sk = serversocket. Register (selector, selectionkey. op_accept );

Logger. debug ("--> Start serversocket. register! ");

// Use the attache function of SK to bind an acceptor. If something happens, the acceptor is triggered.
SK. Attach (New Acceptor ());
Logger. debug ("--> attach (New Acceptor ()! ");
}

Public void run () {// normally in a new thread
Try {
While (! Thread. interrupted ())
{
Selector. Select ();
Set selected = selector. selectedkeys ();
Iterator it = selected. iterator ();
// If selector finds that the channel has an op_accept or read event, the following traversal will be performed.
While (it. hasnext ())
// First trigger an accepter thread for an event
// Trigger socketreadhandler later
Dispatch (selectionkey) (it. Next ()));
Selected. Clear ();
}
} Catch (ioexception ex ){
Logger. debug ("reactor stop! "+ Ex );
}
}

// Run acceptor or socketreadhandler
Void dispatch (selectionkey K ){
Runnable r = (runnable) (K. Attachment ());
If (R! = NULL ){
// R. Run ();

}
}

Class acceptor implements runnable {// inner
Public void run (){
Try {
Logger. debug ("--> ready for accept! ");
Socketchannel c = serversocket. Accept ();
If (C! = NULL)
// Call handler to process the channel
New socketreadhandler (selector, C );
}
Catch (ioexception ex ){
Logger. debug ("Accept stop! "+ Ex );
}
}
}
}

The above code cleverly uses the attetchannel attach function to link hanlder with the channel that may have events. when an event occurs, handler of the corresponding link can be triggered immediately.

Let's look at the handler code:

Public class socketreadhandler implements runnable {

Public static logger = logger. getlogger (socketreadhandler. Class );

Private test = new test ();

Final socketchannel socket;
Final selectionkey SK;

Static final int reading = 0, sending = 1;
Int state = reading;

Public socketreadhandler (selector Sel, socketchannel C)
Throws ioexception {

Socket = C;

Socket. configureblocking (false );
SK = socket. Register (SEL, 0 );

// When the selectionkey is bound to this handler and an event is triggered next, the run method of this class is called.
// See dispatch (selectionkey K)
SK. Attach (this );

// Mark selectionkey as readable for reading at the same time.
SK. interestops (selectionkey. op_read );
Sel. Wakeup ();
}

Public void run (){
Try {
// Test. Read (socket, input );
Readrequest ();
} Catch (exception ex ){
Logger. debug ("readrequest error" + ex );
}
}

/**
* Processing and reading data
* @ Param key
* @ Throws exception
*/
Private void readrequest () throws exception {

Bytebuffer input = bytebuffer. Allocate (1024 );
Input. Clear ();
Try {

Int bytesread = socket. Read (input );

......

// Activate the thread pool to process these requests
Requesthandle (new request (socket, BTT ));

.....

} Catch (exception e ){
}

}

Note that the handler executes attach again. In this way, overwrite the previous acceptor. The next time the Handler has a read event, the handler will be directly triggered. the data read, write, and other processes are started.

After reading data, you can make these data processing threads into a thread pool. In this way, the data is read and immediately thrown into the thread pool to accelerate the processing speed:

Furthermore, we can use multiple selectors to process connection and read events respectively.

A high-performance Java Network Service mechanism is coming into being, and exciting cluster parallel computing is coming soon.

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.