Analysis and code implementation of Java NiO principle and text

Source: Internet
Author: User

Preface:

recently in the analysis of the RPC (remote Procedure call Protocol) of Hadoop, it is a protocol that requests services over a network from a remote computer program without needing to know the underlying network technology. can refer to: http://baike.baidu.com/view/32726.htm) mechanism, found that the implementation of the RPC mechanism of Hadoop is mainly used in two technologies: Dynamic agent (dynamic Agent can refer to the blog:/http) weixiaolu.iteye.com/blog/1477774) and Java NIO. In order to correctly analyze the RPC source code of Hadoop, I think it is necessary to study the principle and implementation of Java NIO first.

This blog I mainly from two directions to analyze Java NIO

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 and client code implementations

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 the Inputstream.read () method is called, and it waits until the data arrives (or times out) to return, as well as when the Serversocket.accept () method is called. will also block until a client connection is returned, and after each client connects, the server initiates a thread to process the client's request. 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've summed up its two-point disadvantage:
1. When the client is a long time, a large number of processing threads are created. And each thread consumes stack space and some CPU time

2. Blocking can lead to frequent context switching, and most context switches may be meaningless.

In this case, the non-blocking I/O has its application foreground.

2. java NIO principle and communication model

Java NiO is used in jdk1.4, which can be said to be "new I/O", or non-blocking I/O. Here's how Java NIO works:

1. All IO events are handled by a dedicated thread and are responsible for distribution.
2. Event-driven: events are triggered when they arrive, rather than synchronized to monitor events.
3. Thread communication: The threads communicate through wait,notify and other means. Ensure that each context switch is meaningful. Reduce unnecessary thread switching.

After reading some of the information, I'll stick to the schematic diagram of the Java nio I understand:

(Note: The process of each thread is probably read data, decoding, calculation processing, encoding, sending the response.) )

The Java NiO server only needs to start a dedicated thread to handle all IO events, how is this communication model implemented? Hehe, let's explore its mysteries together. Java NIO uses two-way channels (channel) for data transfer, rather than one-way streams, which allow us to register events of interest on the channel. There are four types of events:

Event name corresponding values
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 a management channel object, which we call selector, which detects events on one or more channels (channel). We take the server as an example, if a read event is registered on the server's selector, at some point the client sends some data to the server, blocking I/O then calls the Read () method to block the data, and the service side of NiO adds a read event to the selector. The service-side processing thread polls the selector and, if an event of interest is found when accessing selector, handles these events and, if no event of interest arrives, the processing thread blocks until the event of interest arrives. Here's what I understand about the communication model of Java NIO:

Two. Java NIO Server and client code implementations

To better understand Java NIO, a simple code implementation of the server and client is posted below.

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 server * @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 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 ();//binds the channel manager and the channel, registers the Selectionkey.op_accept event for that channel, registers the event, and//When the event arrives, Selector.select () returns, If the event does not reach Selector.select () it will remain blocked. Serverchannel.register (selector, selectionkey.op_accept);} /** * Polling is used to monitor whether there are events on the selector that need to be handled, and if so, to process * @thrOWS IOException */@SuppressWarnings ("unchecked") public void Listen () throws IOException {System.out.println ("Server started successfully! ");//Polling Access Selectorwhile (true) {//When the registered event arrives, the method returns; otherwise, the method will always block Selector.select ();//Get an 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 in case of repeated processing ite.remove ();//Client Request Connection event if (key.isacceptable ()) {Serversocketchannel Server = (Serversocketchannel) key.channel ();//obtain and client-connected channels Socketchannel Channel = Server.accept ();// 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 the connection with the client is successful, you need to set read permissions to the channel in order to receive the client's information. Channel.register (This.selector, selectionkey.op_read);//obtained a readable event} else if (Key.isreadable ()) {read (key);}}} /** * Handles events that read messages sent by clients * @param key * @throws ioexception */public void Read (Selectionkey key) throws ioexception{//server can Read message: Gets the event that occurs when the socket channel Socketchannel channel = (socketchannel) key.Channel ();//Create a read buffer of bytebuffer buffer = Bytebuffer.allocate (ten); channel.read (buffer); byte[] data = Buffer.array (); String msg = new string (data). Trim (); SYSTEM.OUT.PRINTLN ("The server received the message:" +msg); Bytebuffer Outbuffer = Bytebuffer.wrap (Msg.getbytes ()); Channel.write (outbuffer);//Send message back to client}/** * Start service-side test * @throws IOException */public static void Main (string[] args) throws IOException {nioserver Server = new Nioserver (); Server.initse RVer (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 of the server that is connected to the IPs * @param port number of the server to which the ports are connected * @throws ioexception */public void Initclient (St Ring Ip,int Port) throws IOException {//Get a socket channel Socketchannel channel = Socketchannel.open ();// Set the channel to non-blocking channel.configureblocking (false);//Get a channel manager This.selector = Selector.open ();//Client Connection server, in fact, the method does not implement the connection, You need to tune//use Channel.finishconnect () in the Listen () method 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);} /** * Polling is used to monitor whether there are events on the selector that need to be handled, and if so, to process * @throws IOException */@SuppressWarnings ("unchecked") public void Listen ( ) throws IOException {//Polling access Selectorwhile (true) {selector.select ();//iterator iterator for the selected item in selector ite = This.selector.selectedKeys (). iterator (); while (Ite.hasnext ()) {Selectionkey key = (Selectionkey) ite.next ();// Delete the selected key to prevent ite.remove ();//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 (bytebuffer.wrap ("Send a message to the server") ). GetBytes ());//After the connection with the server is successful, you need to set read permissions to the channel in order to receive the information from the server. Channel.register (This.selector, selectionkey.op_read);//obtained a readable event} else if (Key.isreadable ()) {read (key);}}} /** * Handles events that read information sent from the service side * @param key * @throws ioexception */public void Read (Selectionkey key) throws ioexception{//and service side Read Method}/** * Start client Test * @throws IOException */public static void Main (string[] args) throws IOException {nioclient Clien t = new nioclient (); Client.initclient ("localhost", 8000); Client.listen ();}}



Analysis and code implementation of Java NiO principle and text

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.