In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly explains "what is the actual difference between AIO and NIO". Interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Now let the editor take you to learn "what is the actual difference between AIO and NIO"?
1. NIO2.0--AIO
1. To some extent, NIO is still synchronously blocked
Although Channel (Network Channel) and Buffer in NIO can realize non-blocking read/write operation, and Selector provides the function of multiplexing, which makes it possible to manage and use multiple IO channels in one thread, avoiding the problems of traditional IO. However, when Selector calls the select () method for channel selection in NIO, it is still blocked synchronously, and because multiple Channel are registered on Selector, this method blocks multiple IO request operations at the same time, although the select () method can set timeout returns, it is still disadvantageous.
In other words, although NIO provides non-blocking read/write methods in network operations, the IO behavior of NIO is synchronous. For NIO, our business thread is notified when the IO operation is ready (calling the select () method in Selector) (the select () method returns, indicating that there is a ready Channel), and then it is up to this thread to perform IO operations (read/write operations through Channel). In the first generation of NIO, each thread can hold multiple IO channels and choose to use them, but in fact a thread can only choose to operate one IO. The IO operation itself is synchronous.
2. NIO improvement
In order to realize the asynchronous non-blocking IO operation, it is improved on the basis of NIO and upgraded to the second generation NIO--, namely AIO mechanism.
AIO goes a step further than NIO by notifying the thread not when the IO is ready, but after the IO operation has been completed. Therefore, the AIO will not block, and our business logic will become a callback function, which will be triggered automatically by the system after the IO operation is completed. That is, it is equivalent to
In AIO, when reading and writing, you only need to call the read or write method of API directly. Both methods are asynchronous, and for read operations, when there is a stream to read, the operating system passes the readable stream into the buffer of the read method and notifies the application; for write operations, when the operating system finishes writing the stream passed by the write method, the operating system actively notifies the application. In other words, it can be understood that the read/write methods are asynchronous, and the callback function will be called actively after completion.
The following four asynchronous channels are mainly added under the Java.nio.channels package:
AsynchronousSocketChannel
AsynchronousServerSocketChannel
AsynchronousFileChannel
AsynchronousDatagramChannel
In AIO socket programming, the server channel is AsynchronousServerSocketChannel, which provides an open () static factory, a bind () method to bind the server IP address (and port number), and accept () to receive user connection requests. The channel used on the client is AsynchronousSocketChannel, and this channel processing provides read and write methods as well as open static factory methods.
In AIO programming, the event handler class (callback function) is specified after issuing an event (accept read write, etc.). The event handler class in AIO is CompletionHandler. This API defines the following two methods that are called back when an asynchronous operation succeeds and fails.
Void completed (V result, An attachment)
Void failed (Throwable exc, An attachment)
3. The actual difference between AIO and NIO
In the JAVA NIO framework, we talked about an important concept, "selector" (selector). Instead of all the registered channels in the application query, it is responsible for polling for IO events in the operating system, managing the set of currently registered channels, locating the channels on which events occur, and so on.
However, in the JAVA AIO framework, because the application is not a "polling" mode, but a subscription-notification mode, the "selector" (selector) is no longer needed, instead, the channel channel listens directly to the operating system registration. Asynchronous IO uses the "subscribe-notify" mode: the application registers IO snooping with the operating system and then continues to do its own thing. When the IO event occurs in the operating system and the data is ready, the application is notified actively and the corresponding function is triggered. This makes AIO implement asynchronous blocking mode in a real sense. (AIO depends on the implementation of the operating system)
Like synchronous IO, asynchronous IO is supported by the operating system. Microsoft's windows system provides an asynchronous IO technology: IOCP (Imax O CompletionPort,I/O completion port).
Because there is no such asynchronous IO technology under Linux, epoll (an implementation of multiplexing IO technology similar to Selector) is used to simulate asynchronous IO.
2. API usage in AIO
1. Java.nio.channels.AsynchronousChannel: this is an interface that marks an channel that supports asynchronous IO operations. There are three main subclasses: AsynchronousFileChannel, AsynchronousSocketChannel and AsynchronousServerSocketChannel, corresponding to FileChannel, SocketChannel and ServerSocketChannel, respectively. (it's strange why there is no AsynchronousDatagramChannel)
2. AsynchronousChannelGroup: packet management of asynchronous channel for resource sharing. An AsynchronousChannelGroup is bound to a thread pool that performs three tasks: waiting for IO events, processing IO data, and dispatching CompletionHandler. When AsynchronousServerSocketChannel is created, you can pass in an AsynchronousChannelGroup, then the AsynchronousSocketChannel created through AsynchronousServerSocketChannel will belong to the same group and share resources (which can be understood as the equivalent of Selector). AsynchronousChannelGroup needs to be created by binding a thread pool and created by three static methods, which can be adjusted according to the specific application.
Public abstract class AsynchronousChannelGroup {public static AsynchronousChannelGroup withFixedThreadPool (int nThreads, ThreadFactory threadFactory); public static AsynchronousChannelGroup withCachedThreadPool (ExecutorService executor,int initialSize); public static AsynchronousChannelGroup withThreadPool (ExecutorService executor);}
3. CompletionHandler: the callback API for the result of asynchronous IO operation, which is used to define the callback work done after the completion of the IO operation. AIO's API allows two ways to handle the results of asynchronous operations, either by returning Future mode or by registering CompletionHandler, often in the way of CompletionHandler, and these handler calls are dispatched by AsynchronousChannelGroup's thread pool. Obviously, the size of the thread pool is a key factor in performance.
The CompletionHandler API has two methods, corresponding to the callback processing in the case of success, failure, cancellation (through the returned Future):
Public interface CompletionHandler {void completed (V result, An attachment); void failed (Throwable exc, An attachment);}
4. ByteBuffer: responsible for carrying messages that need to be read and written during communication.
AsynchronousServerSocketChannel
It is mainly used in three steps: opening the channel, binding the listening port, and receiving client connection requests.
1. Open (create) a channel
You can create an AsynchronousServerSocketChannel instance by calling the static method open () of AsynchronousServerSocketChannel
Try {AsynchronousServerSocketChannel serverSocket = AsynchronousServerSocketChannel.open ();} catch (IOException e) {e.printStackTrace ();}
Or pass in the AsynchronousChannelGroup parameter in the open () method to set the channel grouping to achieve the sharing of channel resources within the group. If the channel fails to open, an IOException will be thrown
Try {ExecutorService pool = Executors.newCachedThreadPool (); AsynchronousChannelGroup group = AsynchronousChannelGroup.withCachedThreadPool (pool, 1024); AsynchronousServerSocketChannel serverSocket = AsynchronousServerSocketChannel.open (group);} catch (IOException e) {e.printStackTrace ();}
AsynchronousChannelGroup encapsulates the mechanism needed to handle the completion of the Icano operation triggered by an asynchronous channel bound to the group. Each AsynchronousChannelGroup is associated with a thread pool that is used to submit the completion-handlers that handles the Imax O event and distributes the results of asynchronous operations performed on the channels within the group. In addition to handling the Iripple O event, it is possible for the thread pool to handle other tasks that support the completion of asynchronous Iripple O operations. As you can see from the above example, by opening AsynchronousServerSocketChannel by specifying AsynchronousChannelGroup, you can customize the thread pool executed by server channel. If you do not specify AsynchronousChannelGroup, AsynchronousServerSocketChannel is grouped into a default grouping.
two。 Bind listening ports and addresses
Bind the port to listen on by calling the bind () method.
Try {ExecutorService pool = Executors.newCachedThreadPool (); AsynchronousChannelGroup group = AsynchronousChannelGroup.withCachedThreadPool (pool, 1024); AsynchronousServerSocketChannel serverSocket = AsynchronousServerSocketChannel.open (group); int port = 8888; serverSocket.bind (new InetSocketAddress (port));} catch (IOException e) {e.printStackTrace ();}
3. Monitor and receive client connection requests
Listening for client connection requests is done mainly by calling the accept () method. Accept () has two overloaded methods:
Public abstract void accept (A _ MagneCompletionHandler); public abstract Future accept ()
The two overloaded methods behave exactly the same way, either providing a CompletionHandler callback parameter or returning a variable of type Future.
The Future version of the accept method can call the Future.get () method through the Future interface to block waiting for the result of the call and return an AsynchronousSocketChannel object.
Try {ExecutorService pool = Executors.newCachedThreadPool (); AsynchronousChannelGroup group = AsynchronousChannelGroup.withCachedThreadPool (pool, 1024); AsynchronousServerSocketChannel serverSocket = AsynchronousServerSocketChannel.open (group); int port = 8888; serverSocket.bind (new InetSocketAddress (port)); while (true) {Future accept = serverSocket.accept (); AsynchronousSocketChannel socket = accept.get () / / blocking method, get AsynchronousSocketChannel / / use the acquired Socket for network IO operation / / but generally do not use it this way, because this will result in becoming the same as the first generation NIO, so basically use another overloaded method of CompletionHandler}} catch (IOException E1) {e1.printStackTrace () } catch (InterruptedException e2) {e2.printStackTrace ();} catch (ExecutionException e3) {e3.printStackTrace ();}
In contrast to the CompletionHandler callback parameter version, the real data IO processing is not placed in the current thread, but is handled by a callback method. The processing logic code is written in the completed method in CompletionHandler, because this method will successfully receive an AsynchronousSocketChannel in AsynchronousServerSocketChannel, callback execution, and if AsynchronousServerSocketChannel accepts AsynchronousSocketChannel failure, the failed method will be called back.
ServerSocketChannel.accept (serverSocketChannel, new CompletionHandler () {@ Override public void completed (final AsynchronousSocketChannel result, final AsynchronousServerSocketChannel attachment) {/ / receives a new client connection. This accept has completed / / continues to listen for the next client connection to serverSocketChannel.accept (serverSocketChannel,this). / / result is the connection session with the client / / at this time, you can interact with the client through result}.})
Why the accept method is called in the completed method: because when a new client establishes a connection, the completed method is called back, and an AsynchronousServerSocketChannel establishes connections with multiple clients, so you need to continue calling the accept method to accept more client connections.
4. Set TCP connection properties: a connection made through an AsynchronousServerSocketChannel must be a TCP connection, so through this object we can set some properties of the TCP connection.
/ / set socket options, such as keep TCP connection, that is, TCP persistent connection serverSocketChannel.setOption (StandardSocketOptions.SO_KEEPALIVE,true); / / get socket option set boolean keepAlive = serverSocketChannel.getOption (StandardSocketOptions.SO_KEEPALIVE)
Get the local IP address
InetSocketAddress address = (InetSocketAddress) serverSocketChannel.getLocalAddress (); AsynchronousSocketChannel
1. Create a connection
First, you need to call the open method to create an AsynchronousSocketChannel object, and then establish a connection with the server through the connect method. The connect method also has two overloaded versions
One version returns the Future object, and the other passes in the CompletionHandler parameter object
AsynchronousSocketChannel socket = AsynchronousSocketChannel.open (); / / Future future = socket.connect (new InetSocketAddress ("localhost", 8888)); / / future.get () Socket.connect (new InetSocketAddress ("localhost", 8888), socket, new CompletionHandler () {@ Override public void completed (Void result, AsynchronousSocketChannel attachment) {} @ Override public void failed (Throwable exc AsynchronousSocketChannel attachment) {}})
two。 Write data
Build a ByteBuffer object and call the socketChannel.write (ByteBuffer) method to send the message asynchronously, and receive the sending result through the CompletionHandler callback:
ByteBuffer writeBuf = ByteBuffer.wrap ("From socketChannel:Hello i am socketChannel" .getBytes ()); socketChannel.write (writeBuf, null, new CompletionHandler () {@ Override public void completed (final Integer result, final Object attachment) {/ / send completed, result: total number of bytes written} @ Override public void failed (final Throwable exc, final Object attachment) {/ / send failed}})
3. Read data
Build a ByteBuffer with a specified receive length to receive the data, call the socketChannel.read () method to read the message and process the reading result through CompletionHandler:
ByteBuffer readBuffer = ByteBuffer.allocate; socketChannel.read (readBuffer, null, new CompletionHandler () {@ Override public void completed (final Integer result, final Object attachment) {/ / read completed, result: the number of bytes actually read. Result=-1 if there is no data to read in the channel. } @ Override public void failed (final Throwable exc, final Object attachment) {/ / read failed}})
4. You can also set / get socket options (TCP connection properties) through AsynchronousSocketChannel
/ / set socket option socketChannel.setOption (StandardSocketOptions.SO_KEEPALIVE,true); / / get socket option setting boolean keepAlive = socketChannel.getOption (StandardSocketOptions.SO_KEEPALIVE); CompletionHandler
1. The asynchronous channel defined in AIO allows you to specify a CompletionHandler processor to consume the result of an asynchronous operation (that is, when the IO data channel is ready, the method in CompletionHandler is called back and the IO data channel is used for IO processing, which leads to the asynchronous operation. Instead of waiting for the IO channel to be ready or performing the IO operation in the current thread, callback is used). As you can see from the above, most of the asynchronous Imax O operation interfaces in AIO encapsulate an overloaded method with CompletionHandler type parameters, and CompletionHandler can be used to easily deal with the results of asynchronous Imax O operations in AIO. CompletionHandler is an interface with two generic type parameters that declare two interface methods:
Public interface CompletionHandler {void completed (V result, An attachment); void failed (Throwable exc, An attachment);} AIO and problems with NIO
Although NIO and AIOU implement asynchronous non-blocking network IO operation, they still have some disadvantages:
Although the JAVA NIO and JAVA AIO frameworks provide support for multiplexing IO/ asynchronous IO, they do not provide a good encapsulation of the upper layer "information format". For example, the first two do not provide encapsulation for information formats such as ProtocolBuffer and JSON, but the Netty framework provides these data format encapsulation (encoding and decoding functions based on the chain of responsibility pattern)
To write a reliable, easy to maintain, high-performance (pay attention to their sorting) NIO/AIO server application. In addition to the framework itself to be compatible with the implementation of all kinds of operating systems. More importantly, it should also deal with many upper-level unique services, such as client permissions, encapsulation of the above-mentioned information format, and simple data reading. These Netty frameworks provide support for responses.
There is a poll/epoll bug:Selector doesn't block on Selector.select (timeout) in the JAVA NIO framework, and not block means that the utilization of CPU will become 100% (this is the problem of the underlying JNI, and it is actually easy for the upper layer to handle this exception). Of course, this bug can only be reproduced on the Linux kernel. This issue has not been fully resolved in JDK 1.7: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=2147719. Although Netty 4.0 is also encapsulated based on the JAVA NIO framework (an introduction to the NioServerSocketChannel class in Netty has been given above), Netty has handled this bug.
At this point, I believe you have a deeper understanding of "what is the actual difference between AIO and NIO". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.