JAVA 绑定线程到指定CPU上

CPU个数、核数、线程数、JAVA多线程关系

cpu个数、核数、线程数的关系

cpu个数:是指物理上,也及硬件上的核心数;

核数:是逻辑上的,简单理解为逻辑上模拟出的核心数;

线程数:是同一时刻设备能并行执行的程序个数,线程数=cpu个数 * 核数【如果有超线程,再乘以超线程数】

cpu线程数和Java多线程

首先明白几个概念:

(1) 单个cpu线程在同一时刻只能执行单一指令,也就是一个线程。

(2) 单个线程同时只能在单个cpu线程中执行。

(3) 线程是操作系统最小的调度单位,进程是资源(比如:内存)分配的最小单位。

(4)Java中的所有线程在JVM进程中,CPU调度的是进程中的线程。

(5)Java多线程并不是由于cpu线程数为多个才称为多线程,当Java线程数大于cpu线程数,操作系统使用时间片轮转(RR)调度算法,频繁的进行上下文切换,以便并发执行其他线程。

(6)cpu执行Java程序,其根本是执行java代码编译后的操作系统可以识别的指令,cpu执行一条指令的时间是ns级别的(1.6G的cpu执行一条指令,大概需要0.6ns),而cpu上下文切换则需要5000-10000个CPU时钟周期。

(7)受内核限制,Linux系统单个进程最多开启1000个线程,Windows系统单个进程最多开启2000个线程。

(8)默认情况下,Java中每创建一个线程,操作系统会分配1M的栈空间。

那么java多进程,每个进程又多线程,cpu是如何调度的呢?

个人理解:操作系统并不是单纯均匀的分配cpu执行不同的进程,因为线程是调度的最小单位,所以会根据不同进程中的线程个数进行时间分片,均匀的执行每个线程,也就是说A进程中有10个线程,而B进程中有2个线程,那么cpu分给进程的执行时间理论上应该是5:1才合理。

cpu线程数和java线程数有直接关系吗?

个人理解:没有直接关系,正如上面所说,cpu采用分片机制执行线程,给每个线程划分很小的时间颗粒去执行,但是真正的项目中,一个程序要做很多的的操作,读写磁盘、数据逻辑处理、出于业务需求必要的休眠等等操作,当程序在进行I/O操作的时候,线程是阻塞的,线程由运行状态切换到等待状态,此时cpu会做上下文切换,以便处理其他的程序;当I/O操作完成后,cpu 会收到一个来自硬盘的中断信号,并进入中断处理例程,手头正在执行的线程因此被打断,回到 ready 队列。而先前因 I/O 而waiting 的线程随着 I/O 的完成也再次回到 就绪 队列,这时 cpu 可能会选择它来执行。

如何确定程序最佳线程数?

个人理解:如果所有的任务都是计算密集型的,则创建的多线程数 = 处理器核心数就可以了

​ 如果io操作比较耗时,则根据具体情况调整线程数,此时 多线程数 = n*处理器核心数

​ 一般情况程序线程数等于cpu线程数的两到三倍就能很好的利用cpu了,过多的程序线程数不但不会提高性能,反而还会因为线程间的频繁切换而受影响,具体需要根据线程处理的业务考略,不断调整线程数个数,确定当前系统最优的线程数。

CPU亲和性

了解下将进程与 CPU 进行绑定的好处。

进程绑定 CPU 的好处:在多核 CPU 结构中,每个核心有各自的L1、L2缓存,而L3缓存是共用的。如果一个进程在核心间来回切换,各个核心的缓存命中率就会受到影响。相反如果进程不管如何调度,都始终可以在一个核心上执行,那么其数据的L1、L2 缓存的命中率可以显著提高。

所以,将进程与 CPU 进行绑定可以提高 CPU 缓存的命中率,从而提高性能。而进程与 CPU 绑定被称为:CPU 亲和性。

Java绑定线程到指定核心

使用Java-Thread-Affinity

        <!-- https://mvnrepository.com/artifact/net.openhft/Java-Thread-Affinity -->
        <dependency>
            <groupId>net.openhft</groupId>
            <artifactId>Java-Thread-Affinity</artifactId>
            <version>3.2.3</version>
        </dependency>

代码:

 try (AffinityLock affinityLock = AffinityLock.acquireLock(5)) {
            while (true) {
                
            }
  }

运行以后可以发现第6个核心满载100%

参考:

Java如何绑定线程到指定CPU上执行?

java实现将线程绑定到某个CPU核上(线程亲和性)

java高级用法之:绑定CPU的线程Thread-Affinity

posted @ 2022-09-23 09:08  hongdada  阅读(1164)  评论(0编辑  收藏  举报