为什么调用SwingWorker的cancel方法后会立刻终止而非等待当前任务完成
问题原因
- 核心问题出在
taskWorker.cancel(true)的传参上:SwingWorker.cancel()的布尔参数mayInterruptIfRunning设为true时,会直接给正在运行doInBackground逻辑的工作线程发送中断信号。 - 你的代码中调用的
CUtils.sleep(10000)本质是对Thread.sleep()的封装,线程收到中断信号后,sleep会立刻抛出InterruptedException,中断当前休眠逻辑。如果你的工具类没有捕获这个异常,doInBackground会直接跳出执行流,跳过剩余的耗时任务逻辑,直接执行threadDone = true的赋值;如果工具类内部捕获了异常且没有重置中断状态,下一次循环判断!isCancelled()时也会直接返回false,跳出循环。 - 以上两种情况都会导致
threadDone几乎立刻被赋值为true,所以waitThreadToGentlyFinish中的循环刚进入就满足退出条件,不会打印任何#字符。
修复方案
如果要实现「当前轮耗时任务执行完再退出」的优雅停止逻辑,修改如下:
- 调用
cancel时传入false,即taskWorker.cancel(false);,此时不会主动中断正在运行的任务,isCancelled()只会在下一次循环判断时返回true,保证当前轮的耗时任务完整执行完成后再退出循环。 - 如果你的业务逻辑需要兼容中断场景,需要在
doInBackground中手动捕获InterruptedException,自行控制逻辑确保当前轮任务执行完成后再退出循环,同时注意正确处理线程中断状态。
额外提示:SwingWorker是专为Swing桌面应用设计的异步任务工具,在Servlet服务端场景下使用并不合适,建议改用
ScheduledExecutorService实现周期性重复任务,优雅停止的逻辑会更易控制。
内容的提问来源于stack exchange,提问作者Maike
相关产品推荐
相关产品推荐

