Graphic analysis and code implementation of Java NIO principle
Objective:
Recently in the analysis of Hadoop RPC (remote Procedure call Protocol, the remoting protocol, which is a protocol that requests services over a network from a remote computer program without the need to understand the underlying network technology). can refer to: http://baike.baidu.com/view/32726.htm mechanism, found that the RPC mechanism of HADOOP implementation of the main use of two technologies: Dynamic agents (dynamic agents can refer to the blog: http:// weixiaolu.iteye.com/blog/1477774) and Java NIO. In order to be able to analyze the RPC source code of Hadoop correctly, I think it is necessary to study the principle and implementation of Java NIO first.
This blog I mainly analyze Java NIO from two directions
Directory:
A The difference between Java NIO and blocking I/O
1. Blocking I/O communication model
2. Java NIO principle and communication model
Two Java NIO server side and client code implementation
Specific analysis:
A The difference between Java NIO and blocking I/O
1. Blocking I/O communication model
If you have a certain understanding of blocking I/O now, we know that blocking I/O is blocked when calling the Inputstream.read () method, and will not return until the data arrives (or times out), and again, when the Serversocket.accept () method is invoked, is also blocked until a client connection is returned, and after each client connects, the server initiates a thread to process the client's request. The schematic diagram of the communication model for blocking I/O is as follows:
If you analyze it carefully, you will find that there are some drawbacks to blocking I/O. Based on the blocking I/O communication model, I have summed up its two-point disadvantage:
1. When the client is long, a large number of processing threads are created. And each thread takes up stack space and some CPU time
2. Blocking can result in frequent context switches, and most context switches may be meaningless.
In this case, non-blocking I/O has its application prospects.
2. Java NIO principle and communication model
Java NiO is used in jdk1.4, which can be said as "New I/O" or as non-blocking I/O. Here's how Java NIO works:
1. A dedicated thread handles all IO events and is responsible for distribution.
2. Event-driven mechanisms: events are triggered when they arrive, not synchronized to monitor events.
3. Thread communication: Threads communicate with each other through wait,notify. Ensure that each context switch is meaningful. Reduce unnecessary thread switching.
After reading some of the data, I'll post a working schematic of Java NIO that I understand:
(Note: The processing flow of each thread is probably read data, decode, compute, encode, and send a response.) )
The service side of Java NiO only needs to start a dedicated thread to handle all IO events, how is this communication model implemented. Oh, let's explore its mysteries together. Java NIO uses a two-way channel (channel) for data transmission, rather than a one-way stream (stream) where we can register events of interest. There are four kinds of events:
Event name |
corresponding value |
Server-side Receive client connection events |
Selectionkey.op_accept (16) |
Client Connection service-side events |
Selectionkey.op_connect (8) |
Read Events |
Selectionkey.op_read (1) |
Write events |
Selectionkey.op_write (4) |
The server and the client each maintain an object that manages the channel, which we call selector, which detects events on one or more channels (channel). We take the server as an example, if the service side of the selector register read events, at some point the client sent some data to the server, blocking I/O then call the Read () method blocking the reading of data, and NiO's server will add a read event in the selector. The service-side processing thread polls the selector and, if an event of interest is found when accessing the selector, handles the events, and if no event of interest arrives, the processing thread blocks until the event of interest arrives. Here is a schematic diagram of the communication model of Java NIO that I understand:
two. Java NIO server side and client code implementation
To better understand Java NIO, the following is a simple code implementation for both the server and the client.
Service side:
Java code package cn.nio; import java.io.ioexception; import java.net.inetsocketaddress; import java.nio.bytebuffer; Import java.nio.channels.SelectionKey; import java.nio.channels.selector; Import java.nio.channels.ServerSocketChannel; import java.nio.channels.socketchannel; import java.util.iterator; /** * nio service end * @ author path */ public class nioserver { //Channel manager private Selector selector; /** * get a serversocket channel and do some initialization work on the channel * @param port bound port number * @throws IOException */ public Void initserver (int port) throws IOException { // get a serversocket channel Serversocketchannel serverchannel = serversocketchannel.open (); // set Channel to Non-blocking Serverchannel.configureblocking (false); // Bind the channel's corresponding serversocket to port ports serverchannel.socket () . Bind (New inetsocketaddress (port); // Get a channel manager this.selector = selector.open () ; //the channel manager and the channel, and registers the Selectionkey.op_accept event for the channel, after registering the event, //When the event arrives, Selector.select () returns, if the event does not reach Selector.select () Will keep blocking. serverchannel.register (selector, selectionkey.op_accept); } / ** * use polling to monitor the selector for events that need to be handled and, if so, to process * @throws IOException */ @SuppressWarnings ("unchecked") public void listen () throws IOException { SYSTEM.OUT.PRINTLN ("Server-side startup succeeded.") "); // polling access selector & NBsp; while (true) { //the method returns when the registered event arrives; otherwise, the method blocks selector.select (); // get the iterator for the selected item in selector, the selected item is the registered event iterator ite = this.selector.selectedkeys (). Iterator ( ); while (Ite.hasnext ( ) { SelectionKey key = (Selectionkey) ite.next (); // Delete the selected key to prevent duplicate processing &Nbsp; ite.remove (); // Client Request Connection Events if (Key.isacceptable ()) {