Thread.yield 是否与 Java 中的非阻塞 IO 相同
Is Thread.yield same as non blocking IO in Java
我知道非阻塞 IO 不会阻塞调用线程,而是在等待 IO 时释放它去做其他事情。
我刚刚了解了 Thread. yield
方法,该方法允许线程将 CPU 告知 运行 其他线程...技术上产生控制。
这两个东西,非阻塞 IO 和 Thread. yield
听起来和我很相似,所以我想知道,在最基本的层面上,非阻塞 IO 只是 Thread. yield
在什么时候投入使用做 IO?
TL;DR: 不,Thread.yield()
不能也不应该用于 任何事情。
机制看似相似,但yield()
与非阻塞IO无关,也不能用于实现非阻塞IO。这也很麻烦,行为取决于平台,因此应该 not be used.
虽然阻塞 IO 的工作原理是让一个线程在输入流上“锁定自身”并在输入到达时唤醒,但非阻塞 IO 却相反,并且有一个中央 selector(一种本机机制)可以获取输入数据可用时通知。它可以同时观察数千个通道,并在不需要任何关注的通道上花费零资源。当数据在通道上可用时,选择器会将数据定向到工作线程进行处理。它很高效,但也不同于阻塞 IO,而且更复杂。
因为yield()
只告诉CPU“我没有工作要做,在我休息的时候随意运行其他线程”,它仍然以同样的方式工作作为常规 IO。你要避开无事可做的线程,yield就是主动什么都不做,而不是让调度器来决定。
现在你可能认为你可以编写类似下面的东西来模拟非阻塞 IO
List<InputStream> ins ...
while(true) {
for(InputStream in : ins) {
if(in.available() > 0) {
int input = in.read();
// do something with input
}
}
Thread.yield();
}
您可能认为代码就像一个选择器。遍历阻塞的输入流,检查它们是否有数据要读取,如果有,读取数据并处理它,并可能在循环后产生线程以进行良好测量。
上面的代码有缺陷主要是因为调用了InputStream.available()
。它可以用来判断如果呼叫 return 是正数,则呼叫何时 不会 阻塞,但它可以 return 0
并且仍然不会阻塞.您可能(并且很可能会)最终永远循环遍历这些流而不读取任何内容,因为逻辑认为它会阻塞因为 available()
returns 0
只是因为它不能 确定 它不会阻塞。这是阻塞和非阻塞 IO 之间的主要区别。知道读取是否会被 BIO 阻塞的唯一可靠方法是调用 read()
。然后你可能会被卡住。
这是斯蒂芬对 available() in socket programming 问题的很好解释。
我知道非阻塞 IO 不会阻塞调用线程,而是在等待 IO 时释放它去做其他事情。
我刚刚了解了 Thread. yield
方法,该方法允许线程将 CPU 告知 运行 其他线程...技术上产生控制。
这两个东西,非阻塞 IO 和 Thread. yield
听起来和我很相似,所以我想知道,在最基本的层面上,非阻塞 IO 只是 Thread. yield
在什么时候投入使用做 IO?
TL;DR: 不,Thread.yield()
不能也不应该用于 任何事情。
机制看似相似,但yield()
与非阻塞IO无关,也不能用于实现非阻塞IO。这也很麻烦,行为取决于平台,因此应该 not be used.
虽然阻塞 IO 的工作原理是让一个线程在输入流上“锁定自身”并在输入到达时唤醒,但非阻塞 IO 却相反,并且有一个中央 selector(一种本机机制)可以获取输入数据可用时通知。它可以同时观察数千个通道,并在不需要任何关注的通道上花费零资源。当数据在通道上可用时,选择器会将数据定向到工作线程进行处理。它很高效,但也不同于阻塞 IO,而且更复杂。
因为yield()
只告诉CPU“我没有工作要做,在我休息的时候随意运行其他线程”,它仍然以同样的方式工作作为常规 IO。你要避开无事可做的线程,yield就是主动什么都不做,而不是让调度器来决定。
现在你可能认为你可以编写类似下面的东西来模拟非阻塞 IO
List<InputStream> ins ...
while(true) {
for(InputStream in : ins) {
if(in.available() > 0) {
int input = in.read();
// do something with input
}
}
Thread.yield();
}
您可能认为代码就像一个选择器。遍历阻塞的输入流,检查它们是否有数据要读取,如果有,读取数据并处理它,并可能在循环后产生线程以进行良好测量。
上面的代码有缺陷主要是因为调用了InputStream.available()
。它可以用来判断如果呼叫 return 是正数,则呼叫何时 不会 阻塞,但它可以 return 0
并且仍然不会阻塞.您可能(并且很可能会)最终永远循环遍历这些流而不读取任何内容,因为逻辑认为它会阻塞因为 available()
returns 0
只是因为它不能 确定 它不会阻塞。这是阻塞和非阻塞 IO 之间的主要区别。知道读取是否会被 BIO 阻塞的唯一可靠方法是调用 read()
。然后你可能会被卡住。
这是斯蒂芬对 available() in socket programming 问题的很好解释。