This article describes the four IO cases of Java BIO (synchronous blocking IO), pseudo-asynchronous Io,nio (non-blocking io), AIO (asynchronous IO), and compares different IO models.
Directory
1.BIO
2. Pseudo-Asynchronous IO
3.NIO
4.AIO
5. Four kinds of IO comparisons
6.bio\ Pseudo-Asynchronous Io\nio\aio source Download
1.BIO
The server that uses the Bio communication model, usually by a separate acceptor thread, is responsible for listening to the client's connection, after receiving the client connection request, creating a new thread process link connection processing for each client, after processing, return the reply to the client through the output stream, and the thread is destroyed.
The most problematic performance problem of the model, when the client concurrent access increases, the service end path increases, and when the number of threads expands, the performance of the system decreases, and as the amount of concurrency increases, the system can overflow the thread stack, create a new thread failure, and eventually lead to thread downtime or zombie, and can not provide services externally. And the process has a lot of overhead, affecting server performance.
Source code in the Src/main/java/nioinduction/bio, divided into client and server, simple network, threading processing.
2. Pseudo-Asynchronous IO
To address the need for a threading process for a link to a synchronous blocking IO, the concept of "pool" is introduced and the thread pool is added.
When a new client connection is made, the socket of the client is encapsulated as a task (the Java Runnable Interface is implemented) and posted to the back-end thread pool for processing. Because the thread pool can set the size of the message queue and the maximum number of threads, its resources are controllable, and no matter how many clients have concurrent access, it will not cause the exhaustion and downtime of resources.
The pseudo-asynchronous IO Communication framework employs the thread pool implementation, thus avoiding the problem of threading resource exhaustion caused by creating a separate thread for each request. However, because of the synchronization blocking model of the underlying communication, it is impossible to solve the problem fundamentally.
Java output stream InputStream: when the input stream of the socket is read, it blocks until the following three events occur. The data is readable, the available data has been read, a null pointer or an IO exception has occurred.
This means that when the other person sends a data request or the response message is slow (network transmission is slow), the communication thread that reads the write stream will block for a long time, and if the other party wants 100s to complete the message, the IO thread of the read side will also block 100s, during which other access messages can only be queued in the message queue.
Java input stream OutputStream: When calling the Write method of OutputStream writes the output stream, it will block until all the bytes to be sent are written, or an exception occurs. have done TCP/IP know, when the receiver of the message processing slowly, will not be able to read data from the TCP buffer in time, which will cause the sender's TCP window size has been reduced until 0, both sides in keep-alive state, The message sender cannot write the TCP buffer again, and the io,write operation with the synchronized blocking will block indefinitely until the TCP window size is greater than 0 or an IO exception occurs.
Source code under the Src/main/java/nioinduction/pseudoasynchronousio, divided into clients and service side. The client, like the client of the bio, joins the thread pool Executorservice, and the relevant constructors are consulted by the reader.
3.NIO
The NIO library is introduced in JDK1.4, and NiO makes up for the lack of synchronous blocking IO. In all data, NIO is treated as buffer, and any time access to the data in NiO is done through a buffer. The buffer is actually an array. Java NiO is based on multiplexer selector, in simple terms, selector will constantly poll the channel (channel, Full-duplex) that is registered on it, if a channel has a new TCP connection access, read-write event, This channel will be in a ready state and will be polled by the selector, and then the next IO operation can be done by Selectionkey a ready select collection.
A multiplexer can poll multiple channel at the same time, and because the JDK uses epoll instead of the select implementation, there is no limit to the maximum connection handle. (digression, here said EOPLL, select is said under the Linux IO multiplexing, and select, Epoll, clear process concept, please see the source directly).
NIO service-side sequence diagrams
1. Open Serversocketchannel for listening to the client connection, which is the parent pipeline for all client connections.
Serversocketchannel accptorsvr = Serversocketchannel.open ();
2. Bind the listening port and set the connection to non-blocking mode.
Acceptorsvr.socket (). Bind (
new inetsocketaddress (Inetaddress.getbyname ("IP"), port);
Acceptorsvr.configureblocking (FALSE);
3. Create a reactor thread, create a multiplexer, and start the thread.
Selector Selectot = Selector.open ();
New Thread (New Rectortask ()). Start ();
4. Register the Selectsocketchannel on the reactor thread multiplexer selector to listen for accept events.
Selectionkey key = Acceptorsvr.register (Selector,selectionkey.op_accept,iohandler);
5. Multiplexer in the thread run method in the wireless loop in the polling ready for the key.
int num = Selector.select ();
Set Selectkeys = Selector.selectedkeys ();
Iterator it = Selectkeys.iterator ();
while (It.hasnext)
{
Selectionkey key = (Selectionkey) it.next;
/* deal with IO event */
}
6. Multiplexing supervisor hears new user access, handles new access requests, completes TCP three handshake, and establishes physical connections.
Socketchannel sc = ssc.accept ();
7. Set client link to non-blocking mode
Sc.configureblocking (false);
Sc.socket (). Setreuseaddress (true);
...
8. Register the new Access client connection to the reactor thread multiplexer, listening for read operations to read the network messages sent by the client.
Selectionkey key = Sc.register (Selector,selectionkey.op_read,iohangler);
9. Asynchronous read client request message to buffer
int readnumber = Channel.read (Receivedbuffer);
10. Bytebuffer to the codec, if there is half a packet message pointer reset, continue to read the subsequent message, decoding the successful message encapsulated into a task, posted to the business thread pool, business logic processing.
Object message = NULL;
while (Buffer.hasremain ()) {
bytebuffer.mark ();
Object message = decode (bytebuffer);
if (message==null) {
bytebuffer.reset ();
break;
Messagelist.add (message);
}
if (!bytebuffer.hasremain ()) {
bytebuffer.clear ();
}
else Bytebuffer.compact ();
if (Messagelist!=null &!messagelist.isempty ()) {for
(Object messagef:messagelist)
Handletask ( Messagee);
}
11. Encode the Pojo object into Bytebuffer, calling the asynchronous write interface of Socketchannel to send the message asynchronously to the client.
Socketchannel.wite (buffer);
Note: If the Send zone TCP buffer is full, it will cause a half packet to be written, at which point the write operation bit needs to be registered and written until the entire packet message is written to the TCP buffer.
NIO client sequence diagrams (mostly similar to server side)
1. Open Socketchannel, bind client local address (optional, the default system will randomly assign an available local address)
Socketchannel Clientchannel = Socketchannel.open ();
2. Set Socketchannel as Non-blocking mode and set TCP parameters for the connection.
Socketchannel.configureblocking (false);
Socket.setreuseaddress (true);
Socket.setreceivebuffersize (buffer_size);
Socket.setsendbuffersize (buffer_size);
3. Connect to the server asynchronously.
Boolean connected = Clientchannel.connect (new inetsocketadress ("IP", port);
4. Determine whether the connection is successful, if successful, then directly register read state bit to multiplexer, if not successful (asynchronous connection, return False, indicating that the client has already sent the sync package, the server did not return ACK packets, physical connection has not been established-about ACK, sync package, Readers are asked to check TCP/IP three times handshake, four breakup process
if (connect)
clientchannel.register (selector,selectionkey.op_read,iohandler);
else
Clientchannel.register (Selector,selectionkey.op_connect,iohandler);
5. Registers the Op_connect state bit with the multiplexer of the reactor thread, listens for the TCP ACK reply of the server.
Clientchannel.register (Selector,selectionkey.op_connect,iohandler);
6. Create a reactor thread, create a multiplexer, and start the thread.
Selector Selectot = Selector.open ();
New Thread (New Rectortask ()). Start ();
7. Multiplexer in the thread run method in the wireless loop in the polling ready for the key.
int num = Selector.select ();
Set Selectkeys = Selector.selectedkeys ();
Iterator it = Selectkeys.iterator ();
while (It.hasnext)
{
Selectionkey key = (Selectionkey) it.next;
/* deal with IO event */
}
8. Receive connect event for processing
if (key.isconnectable ())
//handlerconnect ();
9. Judge the connection result, if the connection is successful, register read event to Multiplexer
if (Channel.finishconnect ())
registerread ();
10. Register Read Events to Multiplexer
Clientchannel.register (Selector,selectionkey.op_read,iohandler);
11. Asynchronous read client request message to buffer
int readnumber = Channel.read (Receivedbuffer);
12. Bytebuffer to the codec, if there is half a packet message pointer reset, continue to read the subsequent message, decoding the successful message encapsulated into a task, posted to the business thread pool, business logic processing.
Object message = NULL;
while (Buffer.hasremain ()) {
bytebuffer.mark ();
Object message = decode (bytebuffer);
if (message==null) {
bytebuffer.reset ();
break;
Messagelist.add (message);
}
if (!bytebuffer.hasremain ()) {
bytebuffer.clear ();
}
else Bytebuffer.compact ();
if (Messagelist!=null &!messagelist.isempty ()) {for
(Object messagef:messagelist)
Handletask ( Messagee);
}
13. Encode the Pojo object into Bytebuffer, calling the asynchronous write interface of Socketchannel to send the message asynchronously to the client.
Socketchannel.wite (buffer);
Note: The above client and server process, understand on the line, the upper layer of code is not necessarily so written, specific reference to the code to run.
Source code under the Src/main/java/nioinduction/nio, divided into clients and service side.
4.AIO
The concept of a new asynchronous channel is introduced in NIO2.0, and the implementation of H-volume asynchronous socket channel of asynchronous file channel is provided.
The asynchronous channel provides 2 ways to get the result of the operation: The result of the asynchronous operation is represented by the Java.util.concurrent.Futurn class, and a java.nio.channels is passed in when the asynchronous operation is performed.
The implementation class of the Completionhandler interface acts as the backtracking of the operation.
The NIO2.0 asynchronous socket channel, which corresponds to event-driven IO (AIO) in UNIX network programming, does not require a multiplexer (Selector) to poll the registered channel.
Source code under the Src/main/java/nioinduction/aio, divided into clients and service side.
5. Four kinds of IO comparisons
6.bio\ Pseudo-Asynchronous Io\nio\aio source Download
GitHub Address: Https://github.com/orange1438/Netty_Course
Author: orange1438
Source: http://www.cnblogs.com/orange1438/
This article copyright belongs to the author and the blog Garden altogether, welcome reprint, but must retain this paragraph statement without the author's consent, And in the article page obvious position gives the original connection, otherwise reserves the right to pursue legal liability.