关于I / O线程的

时间:2016-05-07 08:31:31

标签: java multithreading

this answer,我知道当java线程等待I / O时,它们处于RUNNABLE状态。

这让我感到困惑,因为根据我的理解,java调度程序在所有RUNNABLE线程之间平均分配CPU资源(让我们忽略优先级)。

为了证明什么是困扰我,请考虑以下事项: 我的进程有1000个线程。其中999个正在等待I / O,这需要一些时间才能完成。左边的一个线程只进行CPU计算。

所有这1000个线程都处于RUNNABLE状态,这意味着时间将在它们之间平分。这将导致1个线程只给出0.1%的CPU,这是荒谬的(当没有其他线程实际需要CPU时)。

我意识到这里有一些我想念的东西,但无法弄清楚它是什么? 是否有其他机制来处理I / O CPU时间消耗?

2 个答案:

答案 0 :(得分:0)

您正在混淆Java线程状态和OS线程状态。虽然有一些共同点,但它们是不同的。

JVM尝试将java状态映射到OS状态,但它不能始终正确地执行此操作。例如,当java代码调用某些本机方法(IO系统调用或任何其他系统调用,JNI等)时,JVM不知道在其本机代码中实际执行了什么线程。因此,JVM将此线程标记为RUNNABLE,直到它退出本机方法。如果此本机系统调用正在执行阻塞IO并且实际上已被阻止(例如,从套接字读取),则OS将使线程进入休眠状态。因此,从操作系统的角度来看,可以从JVM的角度看一些RUNNABLE的线程,并且从OS的角度来看是S状态(休眠)。

在Linux中,可以从ps -eLf输出中找到OS线程状态。有关这些状态的说明,请参见ps手册页。可以使用jstack:将十六进制nid字段转换为十进制值并在ps输出中搜索它来找到java线程名称和本机线程ID之间的映射。

答案 1 :(得分:0)

实际的调度和时间切片取决于操作系统。例如,对于Linux,调度使用启发式计算来基于它们的交互性(I / O绑定与CPU绑定)来更新任务的动态优先级。 在this论文中详述的最新版本中也增加了调度算法。关于这个主题的另一个好的解读(在Linux操作系统的上下文中)是here