Graphic analysis and code implementation _java of Java NiO principle

Source: Internet
Author: User
Tags readable switches

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.) )

How does the service side of Java NiO simply start a dedicated thread to handle all IO events, and 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:

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; /** * Gets a serversocket channel and does 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 () 
  ; 
  Sets the channel to Non-blocking serverchannel.configureblocking (false); 
  Bind the ServerSocket of the channel to Port Serverchannel.socket (). bind (New Inetsocketaddress (port)); 
  Get a channel manager This.selector = Selector.open (); Bind the channel manager to the channel and register 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 any events that need to be handled and, if so, to process * @throws IOException/@SuppressWarnings ("unchecked") pu Blic void Listen () throws IOException {System.out.println ("server-side started successfully!") 
  "); 
   Polling access selector while (true) {//When the registered event arrives, the method returns; otherwise, the method blocks Selector.select (); 
   Gets the iterator for the item selected in Selector, the selected item is the registered event iterator ite = This.selector.selectedKeys (). iterator (); 
    while (Ite.hasnext ()) {Selectionkey key = (Selectionkey) ite.next (); 
    Deletes the selected key to prevent duplicate processing of ite.remove (); Client Request Connection Event if (key.isacceptable ()) {Serversocketchannel Server = (Serversocketchannel) key. Channel ( 
     ); 
     Obtain the Channel Socketchannel channel = Server.accept () with the client connection; 
 
     Set to Non-blocking channel.configureblocking (false); 
     Here you can send a message to the client Oh Channel.write (Bytebuffer.wrap ("Send a message to the client"). GetBytes ()); 
     After successful connection with the client, you need to set read permissions on the channel in order to receive the client's information. Channel.register (This.selector, Selectionkey.op_read); 
    Got the readable event} else if (Key.isreadable ()) {read (key); /** * Handles events that read client-sent information * @param key * @throws IOException/public void Read (selecti 
  OnKey key) throws ioexception{//server can read messages: The socket channel Socketchannel channel = (Socketchannel) Key.channel () where the event occurred; 
  Creates a read buffer Bytebuffer buffer = bytebuffer.allocate (10); 
  Channel.read (buffer); 
  byte[] data = Buffer.array (); 
  String msg = new string (data). Trim (); 
  SYSTEM.OUT.PRINTLN ("Server received information:" +msg); 
  Bytebuffer Outbuffer = Bytebuffer.wrap (Msg.getbytes ()); Channel.write (Outbuffer)//Send message back to client}/** * Boot server Test * @throws ioexception/public static void main (S 
  Tring[] args) throws IOException {nioserver Server = new Nioserver (); 
  Server.initserver (8000); 
 Server.listen (); 
 
 
 } 
 
}

Client:

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.SocketChannel; 
 
Import Java.util.Iterator; 
 
 /** * NIO Client * @author path/public class Nioclient {//Channel manager private Selector Selector;  
 /** * Get a socket channel and do some initialization work on the channel * @param IP-attached server @param port number of the port-attached server * @throws IOException * * public void Initclient (String ip,int port) throws IOException {//Get a socket channel Socketchannel channel = Socketcha 
  Nnel.open (); 
  Sets the channel to Non-blocking channel.configureblocking (false); 
   
  Get a channel manager This.selector = Selector.open (); The client connects to the server, in fact, the method does not implement the connection, needs to be in the Listen () method to adjust//Channel.finishconnect () to complete the connection Channel.connect (new Inetsocketaddress ( 
  Ip,port)); 
  Bind the channel manager to the channel and register the Selectionkey.op_connect event for the channel. 
 Channel.register (selector, selectionkey.op_connect); /** * Monitor SE using polling modeWhether there are events to be handled on the lector, and if so, processing * @throws IOException/@SuppressWarnings ("unchecked") public void Listen () throws 
   IOException {//Polling access selector while (true) {selector.select (); 
   Gets the iterator for the item selected in selector iterator ite = This.selector.selectedKeys (). iterator (); 
    while (Ite.hasnext ()) {Selectionkey key = (Selectionkey) ite.next (); 
    Deletes the selected key to prevent duplicate processing of ite.remove (); 
     The connection event occurs if (Key.isconnectable ()) {Socketchannel channel = (socketchannel) key. Channel (); 
       
     If you are connecting, complete the connection if (channel.isconnectionpending ()) {channel.finishconnect (); 
 
     //Set to Non-blocking channel.configureblocking (false); 
     Here you can send a message to the server Oh Channel.write (a new String ("Send a message to the server"). GetBytes ()) (Bytebuffer.wrap)); 
     After successful connection with the server, you need to set read permissions on the channel in order to receive the information on the server. 
      
     Channel.register (This.selector, Selectionkey.op_read); 
    Got the readable event} else if (Key.isreadable ()) {read (key); 
} 
 
   } 
 
  } /** * Handles events that read information from the server * @param key * @throws IOException/public void read (Selectionkey key) throws ioexception{//and server-side Read method}/** * Start client Test * @throws IOException/public static void main (Stri 
  Ng[] args) throws IOException {nioclient client = new Nioclient (); 
  Client.initclient ("localhost", 8000); 
 Client.listen (); 
 
 } 
 
}

Summary:

Finally the dynamic agent and Java NiO Analysis finished, hehe, the following will analyze the RPC mechanism of Hadoop source code, blog address: http://weixiaolu.iteye.com/blog/1504898. However, if there are objections to the understanding of Java NIO, please discuss it together.
If you want to reprint, please specify the source: http://weixiaolu.iteye.com/blog/1479656

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.