一、线程状态
- new:一个仍未开始的线程
- runnable:一个线程正在被虚拟机执行或者等待cpu去处理(就绪)
- blocked:等待一个监控锁
- waiting:一个线程在等待状态,是因为调用了下面这些方法
Object.wait,Thread.join,LockSupport.park
- timed_waiting:等待超时,时间过了,就不在等待
- terminated:一个线程已经执行完成
二、线程状态之间的转换
创建->运行->终止
创建->运行->等待->运行->终止
创建->运行->阻塞->运行->终止
三、线程中断
- 不正确的线程中止:Thread.stop()方法,破环线程安全,一个锁了的操作,不是同时成功同时失败的
- 正确的线程中止:
- interrupt
- 标志位
线程中断是线程间的协作模式,通过设置线程的中断标志并不能直接终止线程的执行,而是被中断的线程根据中断状态自行处理
注意三个方法:
- interrupt:修改目标线程的中断标志位,若目标线程被sleep wait join阻塞,则会抛出中断异常
- isInterrupted:实例方法,目标线程是不是被中断了
- interrupted:类方法,获取的是当前线程的中断状态,而不是被调用者的中断状态,调用后,会清空中断标识位
四、线程通信
要想实现多个线程之间的协同,如:线程执行先后顺序、获取某个线程执行的结果等等,涉及到线程之间的相互通信,分为下面四类:
- 文件共享
- 网络共享
- 共享变量
- jdk提供的线程协调api
suspend和resume:
- 容易导致线程死锁
- suspend和resume有严格的先后关系,suspend必须出现在resume之前,容易导致线程永久挂起
wait和notifyall
- 先后顺序很重要,notifyall先执行,wait后执行,一个线程会一直处于等待状态
park和unpark
线程调用park则等待许可,unpark方法为指定线程提供“许可(permit)”
不要求park和unpark方法的调用顺序,多次调用unpark之后,再调用park,线程会直接执行,但不会叠加,也就是说,连续多次调用park方法,第一次会拿到许可直接运行,后续调用会进入等待。
对顺序没要求,但是不释放锁
五、伪唤醒
伪唤醒是指线程并非因为notify、notifyall、unpark等api调用而唤醒,是更底层原因导致的,并没有达到被唤醒的条件
六、线程封闭
- ThreadLocal
- 栈封闭——局部变量