java - 为什么 shutdownNow() 方法能够在 Callable 对象中打破 for-loop,但在 Runnable 中却不能这样做,除非我们专门调用了 break?
问题描述
我有这个代码片段,它运行一个带有两个可调用或可运行类型任务的单线程执行程序。这两个任务都运行一个简单的 for 循环计数器,Thread.sleep()
每次迭代都有延迟。第二个任务在第一个任务完成后立即开始。该awaitTermination()
方法应该在执行程序完成之前关闭它。
我知道一旦时间过去就会shutdownNow()
调用当前正在执行的任务,以某种方式设法立即打破第一个任务中的 for 循环,并在对象类型为 时中止第二个任务。现在,如果我将提交对象的类型更改为代码也将按预期终止 for 循环,但这只是因为我在调用.interrupt()
awaitTermination()
MyCallableTask
MyRunnableTask
break
Thread.sleep()
@Override public void run() {
for (int j = 0; j < forLoops; j++) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
break;
}
}
}
如果没有中断,代码会先完成 for 循环然后停止。
我的问题是为什么我们不需要在call()
实施中包含任何中断或返回MyCallableTask
?我的意思是,代码如何在call()
没有任何额外指令的情况下成功地立即打破方法中的 for 循环?
@Override public Void call() throws Exception {
for (int j = 0; j < forLoops; j++) {
Thread.sleep(sleepTime);
}
return null;
}
解决方案
InterruptedException
是一个检查异常。
您要么必须在方法内部处理它(使用 try/catch),要么声明该方法抛出它(或超类)。
可运行的实现不能抛出检查异常,例如InterruptedException
(它的基本声明没有throws Exception
or throws InterruptedException
);Callable
可以,因为它的声明可以。
顺便说一句,您的Runnable
案例应该Thread.currentThread().interrupt()
在中断之前调用,以便调用 Runnable 的任何东西也可以知道它被中断了。
您也不需要将 try/catch 放在循环周围而不是循环内部。
推荐阅读
- mysql - ADODB.Recordset 错误“800a0cc1”
- html - 如何更改导航栏的背景?
- r - R查询中的摘要函数
- c# - Ajax PagedList Reload 每次都返回第一页
- java - Context.openFileInput 和 Context.openFileOutput 之间的同步
- java - 在 JPA 中使用 FetchMode.SUBSELECT 替代休眠 @FetchProfile
- uwp - 如何在 WinJS 中实现二维码扫描器
- mysql - MYSQL,错误 1062
- regex - 从powershell字符串中提取整数
- javascript - firebase auth 不是一个函数