Java线程调度

我的笔记说,有两种主要的线程调度算法类型,抢占式和时间共享。 我想清楚说明这些在Java中如何工作。

据我所知(如果我甚至有点错,请纠正我)抢占允许更高优先级的线程在进入可运行状态时从低优先级线程接管CPU。 它会垄断CPU,直到更高优先级的线程出现,或者它会消耗大部分CPU时间,但优先级较低的线程也有机会运行? 我在这里假设没有调用会放弃像yield()或sleep()这样的CPU的方法。

在时间共享中,更高优先级的线程是否获得更大的CPU时间份额?

我在猜测我的解释(以及我提出的问题)的先发制人不可能是正确的,因为它似乎与时间共享一样! 但我想确定细节。

我想,这是如何实施的? JVM或OS计划线程,还是JVM实现依赖?


首先,我怀疑你的笔记是不正确的,而且应该是非抢先式的,而不是分时(也称为先发制人)。 至少,几十年前我参加操作系统课程时,这就是故障发生的方式,我怀疑它是否发生了变化。

在非抢先式线程(/进程)模型中,每个线程(/进程)被授予CPU的唯一使用权,直到它明确放弃它为止。 这是您在单用户操作系统中找到的模型,例如原始的Windows或Macintosh(以及早于他们的一系列小型机系统)。 正在运行的进程可以明确地yield()它对处理器的控制权,允许另一个线程/进程运行。 当然,对此有许多警告,特别是关于中断处理,但我将在那里留下描述。

在先发制人的aka分时模式中,操作系统可能强制线程/进程产生CPU(即“抢占”它)。 这可能发生在任何地方,但在最简单的情况下,操作系统在每个时钟的每个时钟周期被调用,并决定哪个进程应该为下一个时钟节拍获取CPU。 再次简化,具有最高优先级的进程可以运行; 如果有多个进程具有相同的优先级,那么最近最少运行的算法通常会做出决定。

但是,无论对于所有现代Java实现,它都是决定何时(以及在哪里)运行线程的OS,而不是JVM。


不是线程专家,而是让线程无限期地运行会导致饥饿。 你还是会给一些优先级较低的。 我相信时间分享会让所有线索的数量基本相同。 这些注意事项可能会有所帮助。

从说明:

非抢占式调度:当前进程通过终止或切换到等待状态来释放CPU。 (用于MS Windows系列)

  • 优点:
  • 减少周转时间
  • 不需要特殊的硬件(例如,定时器)
  • 缺点
  • 调度算法的选择有限
  • 抢占式调度:当更重要的进程插入就绪队列或分配的CPU时间结束时,当前进程需要非自愿释放CPU。 (用于Unix和类Unix系统)

  • 优点:
  • 调度算法的选择没有限制
  • 缺点:
  • 额外的开销(例如更频繁的上下文切换,硬件定时器,对数据的协调访问等)

  • 实际上,一个线程是一个抽象的概念。 这只是一个应该执行的原子过程。 原子,我的意思是一个过程,如果你停止它(例如因为它太长而你想执行另一个过程),你需要存储它的当前状态并在之前恢复它以继续执行过程。 现在,这个过程是什么取决于你想要的是什么。 以C语言为例,如果我记得很好,那么这个语言就是为了构建操作系统而设计的,一个过程基本上就是一个程序。 该程序可以要求系统运行其他程序,或者自行分叉以运行克隆(通过使用fork()函数)。 无论它是一个不同的程序还是一个克隆,无论如何它都是一个不同的过程,应该以原子方式执行。 在C中,一个线程是一个程序。 在Java中,线程是扩展线程的类。 在C中,你通过执行它的main()函数来启动一个线程/程序,在Java中你通过执行它的run()方法来运行一个线程/类。 这是针对线程概念的。 它只是程序或执行的Thread实例的通用名称。

    现在,电脑需要并行执行很多东西。 它导致同时管理多个线程。 这里是线程池:它是要执行的线程列表。 而已。 一个简单的列表。 但是有了这个,你有了调度器:你有一定数量的“处理器”,你需要决定在它们上执行哪些线程,但是你不能执行比“处理器”更多的线程。 调度策略的设计应尽可能节省时间,这取决于内容和线程的依赖关系。 可以使用不同的策略,如平衡的执行时间,循环法,优先级等。

    我把“处理器”放在引号中,因为我的意思是“计算单位”。 它可以是计算机的物理处理器或CPU,现在它通常具有2到8个内核(意味着它可以同时运行2-8个线程)并执行CPU指令(通常为RISC)。 它可以是图形卡或GPU的处理器,它有几十或几百个内核,但使用不同的指令集。 Iit也可以是来自Java虚拟机或JVM的处理器,它只能运行单个线程并使用其自己的一组指令(字节码)。 JVM和前两个JVM之间的主要区别在于,CPU和GPU直接与硬件进行交互,而不需要中介,而JVM将自己的字节码转换为RISC指令并要求CPU执行它们。

    CPU使用自己的调度程序来执行它的线程(不仅仅是一个)。 我们称之为“系统线程”。 但是当你用Java编程时,你的执行环境不是系统,而是JVM,它为你提供了系统的抽象(这就是你如何在任何机器上运行Java程序而不关心下面的系统)。 这意味着你不允许直接与系统通信,所以Java为你提供了一种处理线程的方法,允许你创建线程(new Thread())并将它们提供给一个调度器(SwingUtilities,执行者等)。 JVM的工作是如何将Java线程转换为系统线程,以及如何使用Java调度程序来替换系统调度程序。

    所以当你谈论Java中的一个线程时,你不会在系统级别上谈论线程。 这是与系统交互的JVM,以便您有类似的行为。 但是,您的Java线程不由CPU管理,因此您可以独立于CPU的调度策略来请求特定的调度策略。

    Java中的线程调度如何完成? 可从:https://www.researchgate.net/post/How_is_Thread_scheduling_in_Java_done [2017年5月22日访问]。

    链接地址: http://www.djcxy.com/p/84821.html

    上一篇: Java Thread Scheduling

    下一篇: Task scheduler behaviour in Linux