Java Concurrency in Practice:
//Scheduling an interrupt on a borrowed thread. Don’t do this.
private static final ScheduledExecutorService cancelExec = ...;
public static void timedRun(Runnable r,long timeout, TimeUnit unit) {
final Thread taskThread = Thread.currentThread();
cancelExec.schedule(new Runnable() {
public void run() { taskThread.interrupt(); }
}, timeout, unit);
r.run();
}
作者说:
这是一个吸引人的简单方法,但它违反了规则:你在中断线程之前应该知道线程的中断策略。因为timmedrun可以从任意线程调用,所以它无法知道调用线程的中断策略。如果任务在之前完成超时, 取消任务中断线程当timerun返回到它的调用者。我们不知道那时候会运行什么代码,但是结果不会很好。(这是可能的,但出奇地棘手通过使用schedule返回的schedulefuture来消除这种风险取消取消任务
此外,如果任务对中断没有响应,则timerun将响应在任务完成之前不要返回,这可能是在任务结束后很长时间期望的超时(或者根本不超时)。定时运行的服务不会在规定时间后返回很可能会对其造成刺激呼叫者。
我的问题:
- timeout是什么意思?
- 什么是取消任务
超时意味着taskThread
在被中断之前有一个分配的时间间隔来运行任务。取消任务是执行中断的专用任务(在单独的线程上)。
这里的危险是:
-
代码正在中断线程而不是取消任务。被中断的线程可能是线程池的一部分,可能已经完成了任务,并且正在执行另一个完全不同的任务。
-
被中断的任务可能没有适当地使用中断作为完成其工作的指示器,或者它可能正在做一些像阻塞I/O这样无法检查中断状态的事情,因此通常无法保证超时是有效的。