计算机概念
进程与线程
进程
- 系统进行资源分配和调度的基本单位
- 一个进程包含多个线程
- 多个线程共享一个进程的资源
线程
- CPU资源分配和调度的基本单位
- JVM启动main()对应的线程,就是主线程
同步与异步
| 操作 | 阻塞 | 复杂性 |
|---|---|---|
| 同步 | 阻塞 | 简单、顺序 |
| 异步 | 不阻塞 | 代码复杂、并发性高 |
并发与并行
并发
多个任务(线程)通过CPU分配时间片进行切换执行
并行
多个任务同时执行,需要多核CPU进行处理和执行
Java多线程
优势
- 发挥更大的使用CPU的性能,避免浪费资源。例如单核CPU在执行IO操作时,使用多线程CPU在执行IO的同时,还可以执行其他任务。
- 建模简单性
- 异步事件的简化处理
- 响应更灵敏的用户界面
风险
安全性问题
// 线程不安全例子
public class UnsafeCase {
private int count = 0;
public void increment() {
count++;
}
public int getCount() {
return count;
}
public static void main(String[] args) {
UnsafeCase unsafeIncrement = new UnsafeCase();
Runnable incrementTask = () -> {
for (int i = 0; i < 1000; i++) {
unsafeIncrement.increment();
}
};
// 创建多个线程并同时执行自增操作
Thread thread1 = new Thread(incrementTask);
Thread thread2 = new Thread(incrementTask);
thread1.start();
thread2.start();
try {
// 等待两个线程执行完毕
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出最终的计数值,由于线程不安全,结果可能小于预期的2000
System.out.println("Final Count: " + unsafeIncrement.getCount());
}
}
活跃性问题
性能问题
上下文切换:CPU在同一时刻只能被一个线程占用,为了让用户感觉多个线程同时执行,CPU资源的分配采用了时间分片轮转的策略。线程在时间片内占用CPU,执行完成后,让给其他线程进行使用。但是等到下次轮到,得知道上次执行到哪个步骤,这个信息需要保存下来。如果频繁切换就是一笔极大的开销
参考资料:《JAVA并发编程实战》、《JAVA并发编程之美》