简体   繁体   English

关于I / O线程的Java调度机制

[英]Java Scheduling mechanism regarding I/O threads

From this answer , I understand that when java threads wait for I/O, they're in the RUNNABLE state. 这个答案中 ,我了解到当java线程等待I / O时,它们处于RUNNABLE状态。

This confuses me, because from what I understood the java scheduler slices CPU resources equally between all the RUNNABLE threads (let's ignore priority for that matter). 这让我感到困惑,因为根据我的理解,java调度程序在所有RUNNABLE线程之间平均分配CPU资源(让我们忽略优先级)。

To demonstrate what's bugging me, consider that following: My process has 1000 threads. 为了证明什么是困扰我,请考虑以下内容:我的进程有1000个线程。 999 of these are waiting for I/O which will take some time to finish. 其中999个正在等待I / O,这需要一些时间才能完成。 The one left thread only does CPU calculations. 左边的一个线程只进行CPU计算。

All these 1000 threads are in the RUNNABLE state, meaning time will be sliced equally between them. 所有这1000个线程都处于RUNNABLE状态,这意味着时间将在它们之间平分。 This will cause the 1 thread to be given only 0.1% CPU which is absurd (when no other thread actually needs the CPU). 这将导致1个线程仅被给予0.1%的CPU,这是荒谬的(当没有其他线程实际需要CPU时)。

I realize that there's something I miss here, but cannot figure out what it is? 我意识到这里有一些我想念的东西,但无法弄清楚它是什么? Is there an additional mechanism to handle I/O CPU time consumption? 是否有额外的机制来处理I / O CPU时间消耗?

You are confusing Java thread states and OS thread states. 您正在混淆Java线程状态和OS线程状态。 They are different, though have some things in common. 他们是不同的,虽然有一些共同点。

JVM tries to map java states onto OS states but it can't do this always properly. JVM尝试将java状态映射到OS状态,但它不能始终正确地执行此操作。 For example, when java code calls some native method (IO syscall or any other syscall, JNI, etc), JVM has no knowledge of what thread is actually doing in its native code. 例如,当java代码调用某些本机方法(IO系统调用或任何其他系统调用,JNI等)时,JVM不知道在其本机代码中实际执行了什么线程。 So, JVM marks this thread as RUNNABLE until it exits native method. 因此,JVM将此线程标记为RUNNABLE,直到它退出本机方法。 If this native syscall is doing blocking IO and it is actually is blocked (for example, reading from socket), OS will put thread into sleeping state. 如果此本机系统调用正在执行阻塞IO并且实际上已被阻止(例如,从套接字读取),则OS将使线程进入休眠状态。 So, it is OK to have some thread which is RUNNABLE from JVM point of view and is S state (sleeping) from OS point of view. 因此,从操作系统的角度来看,从JVM的角度来看有一些RUNNABLE的线程是可以的,并且是S状态(休眠)。

In Linux, OS thread states may be found out from ps -eLf output. 在Linux中,可以从ps -eLf输出中找到OS线程状态。 Description of these states is available in ps man page. ps手册页中提供了这些状态的描述。 Mapping between java thread names and native thread ids can be found out by using jstack : convert hex nid field into decimal value and search for it in ps output. 通过使用jstack可以找到java线程名称和本机线程id之间的映射:将hex nid字段转换为十进制值并在ps输出中搜索它。

The actual scheduling and time slicing depends on the OS. 实际的调度和时间切片取决于操作系统。 For eg, for Linux the scheduling uses a heuristic calculation to update dynamic priority of tasks based on their interactivity (I/O bound versus CPU bound). 例如,对于Linux,调度使用启发式计算来基于其交互性(I / O绑定与CPU绑定)来更新任务的动态优先级。 Also there have been additions to the scheduling algorithms in recent versions as detailed in this paper. 同时也出现了增加的调度算法中详述最新版本的这个文件。 Another good reading on this topic (in context of Linux OS) is here . 关于这个主题的另一个好读物(在Linux操作系统的上下文中)就在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM