Let's first understand what the so-called Java NiO is.
IO is transmitted by character or byte, rather slowly. And NiO is a block, which is equivalent to a buffer, a piece of
The transmission, the speed is faster
。 At the same time adding multithreading
Control, a NIO stream can transmit multiple blocks at the same time, which is called asynchronous transmission.
;
Traditional
The concurrent type
Server design is the use of blocking network I/O
In a multithreaded mode (a socket link, the server starts a thread to accept the service)
) To achieve, however, by
In the system is often in the network reading and writing in the blocking state, will greatly affect the performance of the system
; from JAVA1. 4 begin to introduce
The NIO (new I/O) API, by using non-blocking type
/ o
To achieve fluent network read and write operations, for the development of high-performance concurrent
-Type server program provides a good solution. This is Java NIO
First of all, the traditional blocking network I/O is insufficient Java platform traditional I/O system is based on byte (byte) and stream (data flow), the corresponding I/O operations are blocking type
,
So the server program also uses blocking I/O
Data read and write operations. In this paper, the TCP long connection mode is used to discuss the design of the server, in order to realize the concurrency requirement of the server program, the system is monitored by a single main thread to monitor the user initiated
Connection requests, which are always blocked, and when a user connection request arrives, the program will start a new thread to uniformly process the read and write operations of the user's data.
The advantages of this model are simple, practical and easy to manage; however, the disadvantage is also obvious: because each client is assigned a thread to process input and output data, its thread is approximately 1:1 the client's ratio.
, as the number of threads increased, the server started a large number of concurrent threads, which greatly increased the system's management overhead for threads
, which will be the main reason for throughput bottlenecks
Second, because of the underlying I/O operation in the synchronous mode, I/O operation of the blocking management granularity is to serve the requested thread unit, there may be a large number of threads will be idle, in a blind state, resulting in low I/O resource utilization, affecting the performance of the entire system.
For a server with a haircut, the system uses more time to switch between blocking I/O and threads than
CPU,
The traditional blocking I/O has become a bottleneck to the performance of the system because of the time of data processing in the storage. Java1.4 version
After the introduction of the NIO Toolkit, the asynchronous input and output of non-blocking I/O is provided
Mechanism
, to improve the performance of the system to provide
The underlying mechanism that can be implemented.
NIO package and its working principle
In view of the shortage of traditional I/O working mode, the NIO Toolkit proposes a buffer (buffers), Channel (pass
Way), Selector (selector), Selector (selector), selectable channel (channel), and
The Selectionkey (select key) is used together to achieve concurrent non-blocking I/O capabilities.
Members of the NIO Toolkit
Buffer (buffer)
1. Basic Concepts
IO is the process of copying data from main memory and external devices (hard disks, terminals, and networks). IO is the operating system's underlying function implementation, the bottom through I/O instructions to complete.
All language runtime systems provide tools to perform higher I/O levels. (c's printf Scanf,java object-oriented encapsulation)
2. Java Standard IO Review
The Java standard IO class library is an object-oriented abstraction of IO. Based on the underlying implementation of the local approach, we do not need to focus on the underlying implementation. Inputstream\outputstream (Byte stream): Send one bytes at a time. Reader\writer (character stream): one character at a time.
3. Introduction to NiO
NIO is the abbreviation of Java New IO, a new API provided in jdk1.4. Sun's official branding features are as follows:
– Provide (buffer) caching support for all original types.
– Character set encoding decoding solution.
–channel: A new raw I/O abstraction.
– A file access interface that supports lock and memory-mapped files.
– Provide multiple-channel (non-bloking) non-blocking, highly scalable network I/O.
This article will be around these characteristics to learn and introduce.
4. Buffer&chanel
Channel and buffer are the two most basic data type abstractions of NIO.
Buffer:
– is a contiguous block of memory.
– is a transit place for NIO data to read or write.
Channel:
– The source of the data or the destination of the data
– The only interface used to provide data to buffer or to read buffer data, buffer objects.
– Asynchronous I/O support
Figure 1:channel and Buffer relation
Example 1:copyfile.java:
Java code package sample; import java.io.fileinputstream; import java.io.fileoutputstream; import java.nio.bytebuffer; Import java.nio.channels.FileChannel; public class copyfile { public static void main (String[] args) throws Exception { String infile = "c:\\ Copy.sql "; String outfile = " c:\\ Copy.txt "; // get input and output streams for source and destination files fileinputstream fin = new fileinputstream ( infile); fileoutputstream fout = new fileoutpUtstream (outfile); // get input output channel filechannel fcin = fin.getchannel (); filechannel fcout = fout.getchannel (); // Create buffer bytebuffer buffer = bytebuffer.allocate (1024); while (true) { The // clear method resets the buffer so that it can accept the read data buffer.clear (); // read data from input channel to buffer &Nbsp; int r = fcin.read (buffer); The // read method returns the number of bytes read, possibly zero, and returns -1 if the channel has reached the end of the stream. if (r == -1) { break; } The // flip method allows the buffer to write newly read data to another channel buffer.flip (); // write data to buffer from output channel fcout.write (buffer); } } }
The internal structure of the buffer is as follows (the following image is copied from the data):
Figure 2:buffer Internal structure
A buffer is mainly controlled by position,limit,capacity three variables to control the process of reading and writing. The meanings of these three variables are shown in the following table:
Parameters |
Write mode |
Read Mode |
Position |
The number of unit data currently being written. |
The position of the unit data currently being read. |
Limit |
Represents the maximum number of units of data and capacity can be written the same. |
Represents the maximum number of units of data that can be read, consistent with the amount of unit data previously written. |
Capacity |
Buffer capacity |
Buffer capacity |
Buffer Common methods:
Flip (): Write mode conversion to read mode
Rewind (): Resets the position to 0, which is typically used for repeated reads.
Clear (): Clears the buffer and prepares to be written again (position becomes 0, limit becomes capacity).
Compact (): Copies the unread data to the head bit of the buffer.
Mark (), Reset (): Mark can mark a position and reset can be reset to that position.
Buffer Common types: Bytebuffer, Mappedbytebuffer, Charbuffer, DoubleBuffer, Floatbuffer, Intbuffer, Longbuffer, ShortBuffer 。
Channel Common types: FileChannel, Datagramchannel (UDP), Socketchannel (TCP), Serversocketchannel (TCP)
A simple performance test was done on the machine. My notebook has a general performance. (Detailed code can be found in the attachment.) See the following example of the Nio.sample.filecopy package for reference data:
– Scene 1:copy a 370M file
– Scene 2: Three threads are simultaneously copied, each thread copies a 370M file
69000
| scene |
fileinputstream+ fileoutputstream |
fileinputstream+ bufferedinputstream+ fileoutputstream |
bytebuffer+ filechannel |
mappedbytebuffer + FileChannel |
| Scene time ( millisecond) ; |
25155 |
17500 |
19000 |
16500 |
| Scene two time ( milliseconds ) | td>
67031 |
74031 |
71016 |
5. Nio.charset
Character encoding decoding: The bytecode itself is just some number and is parsed correctly in the correct context. When storing data in Bytebuffer, it is necessary to consider the encoding method of character set, and to read the display Bytebuffer data involves decoding the character set.
Java.nio.charset provides a solution for encoding and decoding.
As an example of our most common HTTP request, the request must be encoded correctly at the time of the request. The response must be decoded correctly when the response is received.
The following code sends a request to Baidu and gets the results to display. Examples demonstrate the use of CharSet.
Example 2baidureader.java Java code package nio.readpage; import java.nio.bytebuffer; import java.nio.channels.socketchannel; import java.nio.charset.charset; import java.net.inetsocketaddress; import java.io.ioexception; public class baidureader { Private charset charset = charset.forname ("GBK");// create GBK character set private SocketChannel channel; public void Readhtmlcontent () { try { inetsocketaddress socketaddress = new inetsocketaddress ( "www.baidu.com", 80); //step1: Open connection    &NBSp; channel = socketchannel.open (socketAddress);         //STEP2: Send request, use GBK code channel.write (Charset.encode ("GET " + ) http/1.1 " + " \r\n\r\n));    //STEP3: reading data bytebuffer buffer = bytebuffer.allocate (1024);// creates 1024-byte buffers while (channel.read (buffer) != -1) { buffer.flip (); The// flip method is invoked before the read buffer byte operation.      SYSTEM.OUT.PRINTLN (Charset.decode (buffer)); // Convert bytes to strings using the Charset.decode method Buffer.clear ();// Clear Buffer