线程、进程、并发和并行的概念
- 进程:是指一个在内存中正在运行的程序,是操作系统分配资源(文件、io、网络、内存等资源)的基本单位。
- 一个程序文件(也就是我们编写、编译好的程序,是保存在磁盘中的,例如.exe程文件),当我们点击,程序文件就被加载到内存中,也就创建了一个进程。
- 同一个程序文件在内存中可以有多个实例,例如我们可以启动多个qq实例,每个qq就是一个进程。
- 类比java类和对象,类相当于程序文件,对象实例相当于一个进程,我们根据类这个模板,在内存中创建出了一个对象。
- 线程:线程是操作系统调度执行的基本单位,有独立的内存空间(指令、数据、程序计数器等)。
- 一个cpu每次选一个线程来进行执行,取指令和数据到cpu中进行运算再写回内存,每个线程都有被cpu执行的机会,也就是存在上下文切换。
- 上下文切换:cpu在切换到另一个线程B进行执行时,会保存上一个线程A的上下文信息(程序计数器会记录执行到了哪个指令),当切换回A线程,会从上次的地方继续执行。
- 进程和线程的关系
- 一个进程至少有一个线程,这个线程就是主线程,可以包含多个线程。
- 线程依赖于进程存在,一个线程必须属于一个进程。
- 并发:同一时间段内(可以认为很短),有多个任务(线程),需要cpu调度执行,存在上下文切换,同一时刻只能执行一个线程,因为cpu核数有限,忙不过来。
- 并行:同一个时刻可以执行两个或者多个线程,一个核心执行一个线程,取决于cpu核数。
- 可通过任务管理器->性能,查看计算机各项参数
- java获取cpu物理核心数和逻辑核心数
public static void main(String[] args) {
try {
// 获取逻辑处理器数
int logicalProcessors = Runtime.getRuntime().availableProcessors();
System.out.println("逻辑处理器数: " + logicalProcessors);
// 执行 WMIC 命令并读取输出
Process process = Runtime.getRuntime().exec("wmic cpu get NumberOfCores,NumberOfLogicalProcessors");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
int physicalCores = 0;
while ((line = reader.readLine()) != null) {
if (line.contains("NumberOfCores") && line.contains("NumberOfLogicalProcessors")) {
continue;
}
String[] parts = line.trim().split("\\s+");
if (parts.length == 2) {
physicalCores += Integer.parseInt(parts[0]);
}
}
reader.close();
System.out.println("物理核心数: " + physicalCores);
} catch (Exception e) {
e.printStackTrace();
}
}
逻辑处理器数: 8
物理核心数: 4
- 物理核心数为4,逻辑处理器数为8,这是一种超线程技术。这意味着你的系统有4个物理核心,每个核心有2个逻辑处理器。系统能够并行处理的线程数等于逻辑处理器数,也就是8个线程。
- 查看你的操作系统是否支持超线程技术
linux命令:
lscpu | grep "Thread(s) per core"
如果输出显示每个核心有2个线程("Thread(s) per core: 2"),则表示启用了超线程技术
windows命令:
wmic cpu get NumberOfCores,NumberOfLogicalProcessors
比较 NumberOfCores 和 NumberOfLogicalProcessors,如果后者是前者的两倍,则启用了超线程技术
- 超线程技术的优点:在传统的单核心处理器中,如果一个线程因为等待I/O操作或其他原因而阻塞,CPU资源可能会被浪费。超线程技术允许另一个线程在同一个核心上执行,从而提高CPU的利用率。在多任务处理或多线程应用中,超线程技术可以显著提高性能,因为多个线程可以并行执行,减少了上下文切换的开销。
- 逻辑处理器数的意义:在设计线程池时,根据处理器数创建指定数量的线程,充分利用cpu资源。