读书人

间断线程-JCIP7.1读书笔记

发布时间: 2012-08-26 16:48:06 作者: rapoo

中断线程--JCIP7.1读书笔记

[本文是我对Java Concurrency In Practice 7.1的归纳和总结. ?转载请注明作者和出处, ?如有谬误, 欢迎在评论中指正. ]

启动线程之后, 大多数时候我们等待线程运行完成后自动结束. 但是有时我们希望可以提前终止线程的运行:

1. 用户申请取消时. 比如用户点击了取消按钮.

2. 时间限制的任务. 有些任务具有时间限制, 如果在一定的时间内仍然没有得到想要的结果, 我们可能希望终止该任务的运行.

3. 发生特定的事件时. 比如多个线程同时在不同的位置搜索某一文件, 当其中一个线程搜索到了想要的文件, 应该终止其他仍在运行的线程.

4. 发生错误时. 比如发生了磁盘已满的错误, 需要向磁盘写入数据的线程应该提前终止.

5. 应用或者服务被关闭时.

?

java没有直接规定如何安全的提前终止线程的运行, 相反, 提供了不具约束力的协商式机制: 线程A可以请求线程B中断, 但是是否响应, 何时响应, 如何响应中断请求, 由线程B自己决定. 每个线程对象都有一个boolean型的中断标记, 其他线程请求目标线程中断时, 会将目标线程的中断标记设置为true, 然后由目标线程自己决定如何处理. 所以中断线程时, 我们需要知道目标线程的中断机制. 如果我们不知道目标线程会怎样处理中断请求, 不要贸然请求其中断. Thread类中与中断标记相关的方法有:

/** * 执行一项任务, 如果指定时间内没有正常完成, 就取消该任务 */public static void timedRun(Runnable r, long timeout, TimeUnit unit) throws InterruptedException {Future<?> task = taskExec.submit(r);try {// 如果线程池中的线程执行任务过程中该线程发生了中断, 那么调用task的get方法将会抛出InterruptedException异常.// 对于InterruptedException, 按照之前总结的方法处理即可. 此例将其抛给上层.task.get(timeout, unit);} catch (TimeoutException e) {// 如果发生TimeoutException异常, 表明执行时间超时, 此时取消该任务即可} catch (ExecutionException e) {// 发生其他异常时, 不仅要取消任务的执行, 也应该重抛该异常throw launderThrowable(e.getCause());} finally {task.cancel(true);}}

?

线程的中断方式总结:

1. 可以通过设置自定义标记结束线程. 但是这样方式在包含阻塞方法的任务中不适用.

2. interrupt线程. 前提是知道目标线程会怎样处理interrupt请求.

3. 如果是提交给线程池运行的任务, 可以调用Future.cancel.

?

读书人网 >编程

热点推荐