终结任务
@(并发)[java, 并发, Thinking in Java]
1. 在阻塞时终结
1.1. 线程状态
新建
就绪
阻塞
死亡
1.2. 进入阻塞状态
原因:
1. 调用sleep()方法,任务在指定的时间内不会运行,也不会释放锁
2. 调用wait()使线程挂起。直到线程得到norify()或notifyAll()消息,线程才会进入就绪状态。
3. 任务在等待IO操作
4. 任务试图在某个对象上调用其同步控制方法,但是对象锁不可用。
2. 中断
在run()方法中间打断它,必须注意返回良好状态,清除所有事务
方法:
1. Thread类包含interrupt()方法,可以设置线程的中断状态,
2. 直接抛出InterruptedException
尽量避免直接使用Thread的interrupt()方法,转而尽量通过Executor执行所有操作。
Executor的shutdownNow(),它将发送一个interrupt()调用给它启动的所有线程。
Executor的submit()来启动任务,可以持有该任务的上下文,通过返回的Future<>,在其上调用cancel(),可以给单个线程发送interrupt()停止这个线程。
Sleep是可中断的阻塞,IO和同步块是不可中断的阻塞
不可中断的阻塞可以通过关闭任务在其上发生阻塞的底层资源来解决(即shutdownNow()方法)
可中断的阻塞使用cancel或shutdownNow均可以解决
NIO中的IO中断可以通过Future.cancel(ture)解决
同一个互斥可以被同一个任务多次获得,JVM通过计数器统计该锁被几个任务获得
在ReentrantLock上阻塞时,可以直接调用Thread.interrupt()中断
3. 检查中断
通过调用Thread.interrupted()来检查中断,这不仅会说明interrupt()是否被调用过,而且可以清除中断状态。
所有需要被清除的对象创建操作的后面都必须紧跟try-finally语句,从而使得无论run()循环如何退出清理都会发生。