问题描述
试图为自己总结这两个概念之间的区别(因为当我看到人们在一个句子中同时使用这两个概念时,我真的很困惑,比如我试图弄清楚的非阻塞异步 IO"什么意思).
Trying to summarize for myself the difference between these 2 concepts (because I'm really confused when I see people are using both of them in one sentence, like "non-blocking async IO" which I'm trying to figure out what does it mean).
所以,在我的理解中,非阻塞 IO 是主要的操作系统机制,如果有任何数据准备好处理 IO,否则就返回错误/什么都不做.
So, in my understanding non-blocking IO is primary the OS mechanism to process the IO if there is any data ready, otherwise just return error/do nothing.
在异步 IO 中,您只需提供回调,当数据可用时,您的应用程序将收到通知.
In async IO you just provide a callback, and your application will be notified when the data is available.
那么究竟什么是非阻塞异步 IO"?以及如何在 Java 中实现所有这些(标准 JDK,没有外部库,我知道有 java.nio.channels.{Channels, Selector, SelectorKey}
和 java.nio.channels.{AsynchronousSocketChannel}
):非阻塞IO、异步IO、非阻塞异步IO(如果有的话)?
So what is actually "non-blocking async IO"? And how all them can be implemented in Java (standard JDK, without external libs, I know there are java.nio.channels.{Channels, Selector, SelectorKey}
and java.nio.channels.{AsynchronousSocketChannel}
): non-blocking IO, async IO, and non-blocking async IO (if there is such thing)?
推荐答案
要回答这个问题,您必须首先了解没有阻塞异步 I/O 之类的东西.异步的概念表明没有等待,没有阻塞,没有延迟.当您看到非阻塞异步 I/O 时,非阻塞 位仅用于进一步限定该术语中的 async 形容词.如此有效,非阻塞异步 I/O 可能有点多余.
To answer that, you must first understand that there's no such thing as blocking async I/O. The very concept of asynchronism dictates that there's no waiting, no blocking, no delay. When you see non-blocking asynchronous I/O, the non-blocking bit only serves to further qualify the async adjective in that term. So effectively, non-blocking async I/O might be a bit of a redundancy.
I/O主要有两种.同步和异步.同步会阻塞当前的执行线程直到处理完成,而异步不会阻塞当前的执行线程,而是将控制权传递给操作系统内核以进行进一步处理.然后内核在提交的任务完成时通知异步线程
There are mainly two kinds of I/O. Synchronous and Asynchronous. Synchronous blocks the current thread of execution until processing is complete, while Asynchronous doesn't block the current thread of execution, rather passing control to the OS Kernel for further processing. The kernel then advises the async thread when the submitted task is complete
异步渠道组
java 中异步通道的概念是由异步通道组支持的.异步通道组基本上汇集了许多通道以供重用.异步 api 的使用者从组中检索通道(JVM 默认创建一个),通道在完成读/写操作后自动将自己放回组中.最终,异步通道组由 surprise 线程池支持.此外,异步通道是线程安全的.
The concept of Async Channels in java is backed by Asynchronous Channel Groups. An async channel group basically pools a number of channels for reuse. Consumers of the async api retrieve a channel from the group (the JVM creates one by default) and the channel automatically puts itself back into the group after it's completed its read/write operation. Ultimately, Async Channel Groups are backed by surprise, threadpools. Also, Asynchronous channels are threadsafe.
支持异步通道组的线程池的大小由以下 JVM 属性配置
The size of the threadpool that backs an async channel group is configured by the following JVM property
java.nio.channels.DefaultThreadPool.initialSize
其中,给定一个整数值将设置一个该大小的线程池,以支持通道组.否则,通道组的创建和维护对开发人员是透明的.
which, given an integer value will setup a threadpool of that size, to back the channel group. The channel group is created and maintained transparently to the developer otherwise.
以及如何在 Java 中实现所有这些
好吧,我很高兴你这么问.下面是一个 AsynchronousSocketChannel
示例(用于打开一个非阻塞客户端 Socket
到一个监听服务器.)这个示例摘自 Apress Pro Java NIO.2,由我评论:
Well, I'm glad you asked. Here's an example of an AsynchronousSocketChannel
(used to open a non-blocking client Socket
to a listening server.) This sample is an excerpt from Apress Pro Java NIO.2, commented by me:
//Create an Asynchronous channel. No connection has actually been established yet
AsynchronousSocketChannel asynchronousSocketChannel = AsynchronousSocketChannel.open();
/**Connect to an actual server on the given port and address.
The operation returns a type of Future, the basis of the all
asynchronous operations in java. In this case, a Void is
returned because nothing is returned after a successful socket connection
*/
Void connect = asynchronousSocketChannel.connect(new InetSocketAddress("127.0.0.1", 5000)).get();
//Allocate data structures to use to communicate over the wire
ByteBuffer helloBuffer = ByteBuffer.wrap("Hello !".getBytes());
//Send the message
Future<Integer> successfullyWritten= asynchronousSocketChannel.write(helloBuffer);
//Do some stuff here. The point here is that asynchronousSocketChannel.write()
//returns almost immediately, not waiting to actually finish writing
//the hello to the channel before returning control to the currently executing thread
doSomethingElse();
//now you can come back and check if it was all written (or not)
System.out.println("Bytes written "+successfullyWritten.get());
我应该提到对 Async NIO 的支持来自 JDK 1.7
I should mention that support for Async NIO came in JDK 1.7
这篇关于非阻塞 IO 与异步 IO 以及 Java 中的实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!