异步调用和非阻塞调用之间的区别是什么?在阻塞和同步调用之间(请提供示例)?
当前回答
阻塞模型要求初始应用程序在I/O开始时阻塞。这意味着不可能同时重叠处理和I/O。同步非阻塞模型允许处理和I/O重叠,但它要求应用程序反复检查I/O的状态。这就留下了异步非阻塞I/O,允许处理和I/O重叠,包括I/O完成的通知。
其他回答
阻塞:在原语(同步或异步)处理完成后,控制返回到调用进程
非阻塞:调用后控制权立即返回进程
正如你可能从众多不同的(通常是相互排斥的)答案中看到的,这取决于你问谁。在某些领域,这两个术语是同义词。或者它们可能分别指两个相似的概念:
One interpretation is that the call will do something in the background essentially unsupervised in order to allow the program to not be held up by a lengthy process that it does not need to control. Playing audio might be an example - a program could call a function to play (say) an mp3, and from that point on could continue on to other things while leaving it to the OS to manage the process of rendering the audio on the sound hardware. The alternative interpretation is that the call will do something that the program will need to monitor, but will allow most of the process to occur in the background only notifying the program at critical points in the process. For example, asynchronous file IO might be an example - the program supplies a buffer to the operating system to write to file, and the OS only notifies the program when the operation is complete or an error occurs.
在任何一种情况下,目的是允许程序不被阻塞,等待一个缓慢的进程完成-程序如何响应是唯一真正的区别。不同的程序员、不同的语言、不同的平台都不一样。或者这些术语可能指的是完全不同的概念(例如在线程编程中使用同步/异步)。
抱歉,但我不相信有一个唯一的正确答案是全面正确的。
同步意味着按顺序在另一个结果之后启动一个。
异步意味着一起开始,结果上不保证顺序
阻塞是指某些东西导致执行下一步的阻碍。
无阻塞是指不等待任何东西就继续运行,克服障碍。
我敲门,等着他们开门。(我在这里无所事事)
我敲门,如果他们马上开门,我就和他们打招呼,然后走进去等等。如果门没有立刻打开,我就去下一户人家敲门。(我正在做某事,没有闲着)
只有在下雨的时候我才会出去。(依赖关系存在)
我要出去。可能会下雨。(独立事件,发生时间无关紧要)
同步或异步,两者都可以是阻塞或非阻塞的,反之亦然
非阻塞:该函数在栈上时不会等待。
异步:在函数调用离开堆栈后,该函数调用的工作可以继续进行
把这个问题放在java 7中的NIO和NIO.2上下文中,异步IO比非阻塞先进了一步。 使用java NIO非阻塞调用,可以通过调用abstractselectablecchannel . configureblocking (false)来设置所有通道(SocketChannel、ServerSocketChannel、FileChannel等)。 然而,在这些IO调用返回之后,您可能仍然需要控制检查,例如是否以及何时再次读/写等等。 例如,
while (!isDataEnough()) {
socketchannel.read(inputBuffer);
// do something else and then read again
}
使用java 7中的异步api,可以以更通用的方式创建这些控件。 两种方法之一是使用CompletionHandler。注意,两个读调用都是非阻塞的。
asyncsocket.read(inputBuffer, 60, TimeUnit.SECONDS /* 60 secs for timeout */,
new CompletionHandler<Integer, Object>() {
public void completed(Integer result, Object attachment) {...}
public void failed(Throwable e, Object attachment) {...}
}
}