当前位置: 首页 > 面试题库 >

非阻塞IO与异步IO以及Java实现

柴高岑
2023-03-14
问题内容

尝试为自己总结这两个概念之间的区别(因为当我看到人们在一句话中同时使用这两个概念时,我感到非常困惑,例如“ Non-blocking async
IO”,我试图弄清楚它是做什么的)意思)。

因此,以我的理解,无阻塞IO是操作系统的主要机制,如果有任何可用数据,则该OS处理IO,否则仅返回错误/不执行任何操作。

在异步IO中,您仅提供回调,当数据可用时,系统将通知您的应用程序。

那么,实际上什么是“非阻塞异步IO”?以及如何在Java中实现它们(标准JDK,没有外部库,我知道有java.nio.channels.{Channels, Selector, SelectorKey}java.nio.channels.{AsynchronousSocketChannel}):非阻塞IO,异步IO和非阻塞异步IO(如果有的话)?


问题答案:

那么,实际上什么是“非阻塞异步IO”?

要回答这个问题,您必须首先了解没有 阻塞异步I / O 这样的事情。异步的概念要求没有等待,没有阻塞,没有延迟。当您看到 非阻塞异步I / O时
非阻塞 位仅用于进一步限定该术语中的 异步 形容词。如此有效地, 非阻塞异步I / O 可能有点冗余。

I / O主要有两种。 同步异步同步会阻塞当前执行线程,直到处理完成为止 ,而
异步不会阻塞当前执行线程,而是将控制权传递给OS内核进行进一步处理。 然后,当提交的任务完成时,内核会通知异步线程

异步通道组

Java中的异步通道的概念由异步通道组支持。异步通道组基本上会汇集多个通道以供重用。异步api的使用者从组中检索一个通道(JVM默认情况下会创建一个通道),并且该通道在完成其读/写操作后会自动将其自身放回到该组中。最终,异步通道组由支持
惊喜 ,线程池。同样,异步通道也是线程安全的。

支持异步通道组的线程池的大小由以下JVM属性配置

java.nio.channels.DefaultThreadPool.initialSize

给定一个整数值,它将设置该大小的线程池,以支持通道组。渠道组的创建和维护对开发者是透明的。

以及如何用Java实现它们

好吧,很高兴你问。这是一个示例AsynchronousSocketChannel(用于向Socket侦听服务器打开非阻塞客户端。)此示例摘自Apress
Pro Java NIO.2,我对此进行了评论:

//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());

编辑:我应该提到对异步NIO的支持来自JDK 1.7



 类似资料:
  • 试图为自己总结这两个概念之间的区别(因为当我看到人们在一个句子中同时使用这两个概念时,我真的很困惑,比如“非阻塞异步IO”,我试图弄清楚它是什么意思)。 因此,在我的理解中,非阻塞IO是主要的OS机制,如果有任何数据准备就绪,它将处理IO,否则只返回错误/不做任何事情。 那么实际上什么是“非阻塞异步IO”呢?以及如何在Java(标准JDK,没有外部库,我知道有和)中实现所有的IO:非阻塞IO、异步

  • 非阻塞 IO 仅对在 Servlet 和 Filter(2.3.3.3节定义的,“异步处理”)中的异步请求处理和升级处理(2.3.3.5节定义的,“升级处理”)有效。否则,当调用 ServletInputStream.setReadListener 或ServletOutputStream.setWriteListener 方法时将抛出IllegalStateException。为了支持在 Ser

  • Web 容器中的非阻塞请求处理有助于提高对改善 Web 容器可扩展性不断增加的需求,增加 Web 容器可同时处理请求的连接数量。servlet 容器的非阻塞 IO 允许开发人员在数据可用时读取数据或在数据可写时写数据。非阻塞 IO 仅对在 Servlet 和 Filter(2.3.3.3节定义的,“异步处理”)中的异步请求处理和升级处理(2.3.3.5节定义的,“升级处理”)有效。否则,当调用 S

  • Go提供的网络接口,在用户层是阻塞的,这样最符合人们的编程习惯。在runtime层面,是用epoll/kqueue实现的非阻塞io,为性能提供了保障。 如何实现 底层非阻塞io是如何实现的呢?简单地说,所有文件描述符都被设置成非阻塞的,某个goroutine进行io操作,读或者写文件描述符,如果此刻io还没准备好,则这个goroutine会被放到系统的等待队列中,这个goroutine失去了运行权

  • 我正在研究反应式编程,我怀疑它是否是非阻塞IO的Java REST web服务的实现。Java Servlet 3.1规范引入了一些接口,以实现非阻塞web请求。 我的问题是: Netty是否实现了该规范,而Tomcat、JBoss和Jetty没有实现 谢谢。

  • 我认为下面的流量链将通过事件循环放置/执行(像JS)。因此,运行下面的代码将首先打印阻塞循环&然后将执行通量链。 但是,整个通量总是先执行,然后才移动到循环。[我确实有一些语句正在阻塞。但是有两个阶段] 当我们使用reactor时,通过使用一些调度程序来实现异步/非阻塞行为的唯一方法? 如果我不使用任何调度器,并让代码使用当前线程执行,那么即使对于IO密集型应用程序,使用WebFlux而不是Spr