Java blocking IO and non-blocking IO

Source: Internet
Author: User

Io:
IO is the process of copying data from main memory and external devices (hard disks, terminals, and networks). IO is the underlying functional implementation of the operating system, which is done through I/O directives.

Blocking and non-blocking:
A bus from a to B, there are many points on the road may be people get off the train. The driver does not know which points will have who will get off the car, for need to get off the person, how to handle better?

    1. The driver periodically asks if each passenger arrives at the destination, and if someone says so, the driver stops and the passenger gets off. (similar to block type)
    2. Each person tells the conductor his or her destination, then sleeps, the driver only interacts with the conductor, and at some point the conductor notifies the passenger to alight. (similar to non-blocking)
      It is clear that each person arriving at a destination can be considered a thread and the driver can be considered a CPU. Inside the block, each thread needs constant polling, context switching, to achieve the result of finding the destination. In a non-blocking way, each passenger (thread) sleeps (sleeps) and wakes up only when the real external environment is ready, so that the wake is definitely not blocked.

Blocking I/o: (Traditional IO)
As an example of a network application, in the traditional IO mode (blocking IO) It is necessary to listen for a serversocket, to accept the requested connection to serve it (the service usually includes processing the request and sending the response) is the life cycle diagram of the server, where the part marked with the thick black line indicates that I/O blocking occurs.

This approach, when encountering multiple requests, can only wait for the previous request to complete before the new request is processed, so it is common to use a thread (a large number of threads) to handle blocking I/O in Java. The code is as follows

public class TCPServer {public    static void Main (string[] args) {        try {            ServerSocket ss = new ServerSocket (100 (xx);            SYSTEM.OUT.PRINTLN ("Server start ...");            while (true) {                Socket s = ss.accept ();                New Logicthread (s);//Open a thread to process the request, which calls Inputstream.read () Read request information            }        } catch (Exception e) {            E.printstacktrace ();}}}    

You can analyze each specific step of creating a server. First create the ServerSocket

ServerSocket server=new ServerSocket (10000);

Then accept the new connection request

Socket newconnection=server.accept ();//Blocking

Processing requests in Logicthread

InputStream in = Newconnection.getinputstream (), InputStreamReader reader = new InputStreamReader (in); BufferedReader buffer = new BufferedReader (reader); Request Request = new request (), while (!request.iscomplete ()) {    String line = Buffer.readline ();//Block        Request.addline (line);}

The life cycle is as follows:

The traditional IO mode (blocking I/O) is blocked when the Inputstream.read ()/buffer.readline () method is called, and it waits until the data arrives or the buffer is full or times out, and produces a lot of string type garbage. Although StringBuffer optimizations can be used, the Serversocket.accept () method 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. and multithreading handles multiple connections. Each thread has its own stack space and consumes some CPU time. Each thread will block out when it encounters an external unprepared. The result of blocking is a lot of process context switching. And most of the process context switches may be meaningless. For example, if a thread listens on a port, only a few requests come in a day, but the CPU has to do a context-switching attempt for that thread, and most of the switching ends up blocking.

Non-blocking I/O (NIO): can also be said as "New I/O"
Core class:
1.Buffer provides (buffer) cache support for all the original types.
2.Charset Character set encoding and decoding solution
3.Channel a new raw I/O abstraction for reading and writing to the buffer type, which can be considered a connection, either to a particular device, to a program, or to a network. The class hierarchy chart for the channel is as follows

Readablebytechannel and Writablebytechannel are used for reading and writing respectively.
Gatheringbytechannel can write data from more than one buffer at once to the channel, whereas Scatteringbytechannel can read the data from the channel at once into multiple buffer. You can also set the channel to be a blocking or non-blocking I/O operation service.
To enable the channel to be compatible with traditional I/O classes, the Channel class provides a static method to create a stream or reader
4.Selector
In the past blocking I/O, we generally know when to read or write to the stream because the method call is returned when the stream is ready. But with non-blocking channels, we need some way to know when the channel is ready. In the NIO package, the design of the selector is for this purpose. Selectablechannel can register a specific event instead of notifying the app when an event occurs, and the channel trace event. Then, when the app calls any of the selection methods on selector, it looks at the registered channel to see if any events of interest occur.

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.
      As shown in the following:

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

The server side of the

Java NiO only needs to start a dedicated thread to handle all IO events. 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:
Server receive Client Connection event selectionkey.op_accept (+)
Client Connection service side event Selectionkey.op_connect (8)
Read Event Selectionkey.op_read (1)
Write event Selectionkey.op_write (4)
The server and the client each maintain a management channel object, which we call selector, which detects one or more channels ( Channel) on the event. 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.

Complete non-blocking IO instance

/** * NiO Server */public class Nioserver {//Channel manager private Selector Selector; /** * Get a serversocket channel, and do some initialization work on the channel * @param port number bound by ports * @throws IOException */public void Init Server (int port) throws IOException {//Get a serversocket channel serversocketchannel Serverchannel = ServerSocket        Channel.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 (); The channel manager is bound to the channel, and the Selectionkey.op_accept event is registered for that channel, and after the event is registered,//When the event arrives, Selector.select () returns if the event does not reach Selector.select ()        will always block.    Serverchannel.register (selector, selectionkey.op_accept);    }/** * Polling is used to listen for events that need to be handled on selector, and if so, to process * @throws IOException */@SuppressWarnings ("unchecked") public void Listen () throws IOException {System.out.println ("Server started successfully!        "); Polling Access SelectoR while (true) {//When the registered event arrives, the method returns; otherwise, the method will always block Selector.select ();            Gets 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 ite.remove () from being processed repeatedly; 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); A readable event was obtained} else if (Key.isreadable ()) {read (key); }}}}/** * Handles events that read messages sent by clients * @param key * @throws IOException */Public VO ID read (Selectionkey key) throws ioexception{//server readable message: Get event occurred socket Channel Socketchannel channel = (Socketcha        Nnel) Key.channel ();        Creates a read buffer Bytebuffer = bytebuffer.allocate (1024);        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 Ma        In (string[] args) throws IOException {nioserver Server = new Nioserver ();        Server.initserver (8000);    Server.listen (); }}/** * NIO client */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 port * @param the port number of the server to which the ports are connected * @throws Ioexc Eption */public void initclient (String ip,int port) throws IOException {//Get a socket channel Socketchann        El Channel = Socketchannel.open ();        Set 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 execution does not implement the connection, need to tune//with Channel.finishconnect () in the Listen () method, in order to complete the connection channel.connect (new Inetsocketad        Dress (ip,port));        Binds the channel manager and the channel, and registers the Selectionkey.op_connect event for that channel.    Channel.register (selector, selectionkey.op_connect);    }/** * Polling is used to listen for events that need to be handled on selector, and if so, to process * @throws IOException */@SuppressWarnings ("unchecked")            public void Listen () throws IOException {//Polling access selector while (true) {selector.select (); Gets the iterator for the selected item in selector Iterator ite = this.selector.seLectedkeys (). iterator ();                while (Ite.hasnext ()) {Selectionkey key = (Selectionkey) ite.next ();                Delete the selected key to prevent ite.remove () from being processed repeatedly;                            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, in order to receive the information from the server, you need to set the Read permission to the channel.                    Channel.register (This.selector, Selectionkey.op_read);                A readable event was obtained} else if (Key.isreadable ()) {read (key);        }            }}}/** * Handles events that read information sent from the service side * @param key * @throws IOException */public void read (Selectionkey k        EY) throws ioexception{//server readable message: Gets the event that occurs when the socket channel Socketchannel channel = (Socketchannel) key.channel ();        Creates a read buffer Bytebuffer = bytebuffer.allocate (1024);        Channel.read (buffer);        byte[] data = Buffer.array ();        String msg = new string (data). Trim (); SYSTEM.OUT.PRINTLN ("Client received message:" +msg);//Bytebuffer Outbuffer = Bytebuffer.wrap (Msg.getbytes ());//Channel.write (ou Tbuffer);//Send message back to server side}/** * Start client Test * @throws IOException */public static void Main (string[] Arg        s) throws IOException {nioclient client = new Nioclient ();        Client.initclient ("localhost", 8000);    Client.listen (); }}

Reference
http://www.iteye.com/topic/834447
http://weixiaolu.iteye.com/blog/1479656
Http://www.360doc.com/content/12/0604/15/9579107_215842144.shtml

Java blocking IO and non-blocking IO

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.