关于设计的一般问题。我有几个线程需要在后台运行,基本上是一些数据库上传/故障处理任务。全部都有以下流程模式:
public class Worker implements Runnable {
private AtomicBoolean isAlive = new AtomicBoolean(true);
....
public void run() {
while (isAlive.get()) {
// do some work here, slightly heavy
if (Thread.interrupted()) {
// checking Thread.interrupted() as the code above
// can take a while and interrupt may happen before
// it gets here.
isAlive.setBoolean(false);
break; // to exit faster
}
try { Thread.sleep(sleepTime); }
catch (InterruptedException e) {
isAlive.setBoolean(false);
break; // to exit faster
}
}
cleanUp(); // e.g. close db connections etc
}
}
现在我希望能够中断线程,以便它可以优雅地突破while循环并运行cleanUp()
方法。
有很多方法可以做到这一点,列举一些:
在Runnables
中关闭Threads
,然后使用interrupt()
方法:
List<Thread> threadList =...
for (int i < 0; i < threadCount; i++) {
Thread t = new Thread(new Worker());
threadList.add(t);
t.start()
}
// later
for (Thread t : threadList) { t.interrupt(); }
ThreadPoolExecutor,然后使用shutdownNow()
:
ThreadPoolExecutor executor = new ....;
executor.execute(new Worker());
// some lines else later
executor.shutdownNow(); // shutdown() doesn't interrupt?
处理此类工作流程的方法是什么?为什么?欢迎所有想法。
答案 0 :(得分:0)
总而言之,我个人认为将isAlive
设置为false
是最干净的。
根据我的知识,interrupt()
是本机代码,这是远离它的原因。
不要忘记将boolean
设置为volatile
。
答案 1 :(得分:0)
我认为两者都是可接受的方法。如果你有很多线程,我会使用线程池方法来更容易管理。如果你只有一个(也许是两个)线程,我会单独打断它们。
正如MouseEvent所说,不使用中断并使用isAlive变量(在您的实现中似乎毫无意义)会更清晰。但是,这意味着您需要关闭或关闭每个实例(仍然是一个好的方法)
另外,我会在try-catch-finally语句中包含整个方法,您可以捕获中断并在finally子句中进行清理。