一、线程切换(上下文切换)
当一个线程需要切换到另一个线程时,将该线程在CPU寄存器中的资源放入缓存中,将另一个线程需要的资源从缓存中取出放入CPU寄存器并开始执行。
二、线程分类
- CPU密集型:线程大多数时间在执行CPU运算;
- IO密集型:线程大多数时间在执行IO;
- 混合型:大多数线程既有CPU运算和又有IO;
三、线程数量选择
计算公式:
N_thread = N_cpu * U_cpu *(1+W/C)
W:线程等待时间
C:线程利用CPU计算时间
(特例:线程运行时间与等待时间相等,所以发挥100%CPU的性能时,刚好用两个线程)
可以利用Profiler/Arthas来测试实际中线程的W和C;
四、线程状态
- New
- Runnable(Ready / Running)
- Timed Waiting
- Waiting
- Blocked
- Terminated
五、线程的中断
-
interrupt()
设置某个线程的中断标志为true,默认为false; -
isInterrupted() — 优雅的退出线程
查询某个线程的中断标志位的值,不重置,进入if判断体,则可以在里面编写线程退出的方法,使得线程安全退出; -
static interrupted()
查询当前线程的中断标志位,并且重置;
interrupte的线程如果处于sleep或者wait或者join状态则会抛出异常,但是对于正在竞争锁(或者Synchronized)的线程此时不会抛异常。(可以用lock.lockInterruptibly()上锁,则可以用interrupt()方法来使得线程抛异常)
六、线程的结束
- (废弃)stop():直接停止,释放所有锁,不做善后处理;
- (废弃)suspend() / resume():暂停和继续,不会释放锁,不调用resume的的话造成锁不释放;
- volatile变量标志位:变量需要与run方法循环体内参数无关,且当线程wait,sleep时无法停止;
- interrupt标志位:优雅的停止,且支持线程wait和sleep状态下的结束;
七、并行,并发
- 并行是多核心使得多个线程同时执行,因为一个变量在内存中不可能同时被多个线程更改,所以并行不会有并发的问题;
- 并发是一个核心轮流执行多个线程,同一时刻只有一个线程在运行,只不过每个时刻独立的线程会修改同一个变量,最终导致有些线程的修改结果被其他线程覆盖。