java线程是否可以在多个CPU上运行

https://www.cnblogs.com/King-Gentleman/p/4279150.html
https://www.zhihu.com/question/64072646/answer/235691669

先看下java线程和内核线程,线程调度器的关系
JVM线程其实是使用了内核线程的一个高级接口即所谓轻量级进程【是有内核实现的】的概念与系统内核线程(每个内核线程视为内核的一个分身)一比一的关系来执行任务逻辑,从用户态到内核态的过程后, 内核通过操纵调度器对线程进行分配资源,负责将任务给各个处理器上处理执行;因此创建线程的过程会消耗一定的系统资源,因此一个系统支持的轻量级进程数量是有限的。

目前主流的操作系统都提供的线程实现,java则提供的线程实现方法都是native的,因为不同的硬件和操作系统提供线程调度方式并不尽相同,所以java没用采用和平台无关的统一手段来实现。
实现线程的主要3种方式:使用内核线程实现,使用用户线程实现,使用用户线程加轻量级进程混合实现。(用户线程这里就不贴了,java在jdk 1.2之前基于用户线程实现,在1.2之后,基于操作系统的原生线程模型来实现,在每个平台上都不尽相同,比如在windows和linux下都是采用一对一的线程模型实现,在Solaris平台,采用都是一对一或者多对多来实现(solaris 同时支持一对一和多对多))

内核线程(KLT)就是直接由操作系统内核支持的线程,这种线程由内核来完成线程切换。
程序一般不会直接使用内核线程,而是去使用内核线程的一种高级接口—轻量级进程(LWP),轻量级进程就是我们所讲的线程,这种轻量级进程与内核线程之间1:1的对应关系。
java线程是否可以在多个CPU上运行_第1张图片

线程失去占用cpu时参数变化:
主动失去cpu:(1)调用sleep,delay函数使用线程放弃CPU;(2)等待信号量,互斥锁,事件,邮箱或消息队列过程中调用suspend使线程挂起。
在线程主动失去CPU时,程序都会在rt_thread_suspend函数中执行rt_schedule_remove_thread函数,将当前线程从调度器中移除。
在rt_schedule_remove_thread函数中执行rt_list_remove(&(thread->tlist));将当前线程从调度器中移除,同时将该线程优先级对应的位图变量所在位清0。

被动失去cpu:(1)线程的时间片耗尽,被迫放弃CPU;(2)系统产生中断,线程暂时失去CPU,一旦中断例程执行完,还是会还原,这些是由硬件自动完成的。
被动失去CPU时调用线程让出rt_thread_yield函数(这里指(1),(2)完全由硬件来完成,不需要软件干预),此函数中程序会执行rt_list_remove(&(thread->tlist));即将当前线程从调度器中移除,
然后再执行rt_list_insert_before((rt_thread_priority_table[thread->current_priority]),&(thread->tlist));将当前线程加入到调度器中对应优先级的就绪线程链表末尾
紧接着执行rt_schedule();重新调度线程。在被动失去CPU的过程中,程序并未操作与获取线程最高优先级算法相关的几个参数。

如果一个线程执行时间很长,由以上我们可以推测出一个线程在当前CPU时间片耗尽,这个线程会重新进入线程调度器等待CPU,当下次争抢到CPU的时候可能就换成另外一个CPU了。

    public static void main(String[] args) {
        new Thread(() -> {
            while (true) {
            }
        }).start();
    }

java线程是否可以在多个CPU上运行_第2张图片
java线程是否可以在多个CPU上运行_第3张图片
执行代码前后监控可以看出明显有多个CPU使用率很高

你可能感兴趣的:(java,随笔,java)