使用中断Java Runnable和运行清理的首选方法是什么?
关于设计的一般问题。我有几个线程需要在后台运行,基本上是一些数据库上传/故障处理任务。这些都具有以下流动模式:使用中断Java Runnable和运行清理的首选方法是什么?,java,multithreading,concurrency,interrupt,Java,Multithreading,Concurrency,Interrupt,关于设计的一般问题。我有几个线程需要在后台运行,基本上是一些数据库上传/故障处理任务。这些都具有以下流动模式: public class Worker implements Runnable { private AtomicBoolean isAlive = new AtomicBoolean(true); .... public void run() { while (isAlive.get()) { // do some wo
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()
方法
有很多方法可以做到这一点,下面列出一些:
线程中的可运行程序
踢出,然后使用中断()
方法:
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(); }
处理这种工作流的方法是什么?为什么?欢迎所有想法。总之,我个人认为将
isAlive
设置为false
是最干净的。
据我所知,interrupt()
是本机代码,这本身就是远离它的原因
别忘了将
布尔值设置为volatile
我认为这两种方法都是可以接受的。如果你有很多线程,我会选择线程池方法,以便于管理。如果你只有一个(也许两个)线程,我会分别中断它们
正如MouseEvent所说,不使用中断并使用isAlive变量(在您的实现中似乎毫无意义)会更干净。但是,这意味着您需要关闭或关闭每个实例(这仍然是一个好方法)
另外,我将在try-catch-finally语句中围绕整个方法,在其中捕获中断并在finally子句中进行清理。编辑并添加代码以更改isAlive,我将中断循环,使其更快退出。最后试着抓住——好主意。实际上,在try子句中添加更多代码/更慢的代码会对性能造成影响吗?不。。。除非抛出异常,否则不会造成性能损失。此外,isAlive检查正好在中断检查之前。我想两个人会同时把你踢出去。如果有任何性能提升,它将远小于一毫秒。添加了一些关于我为什么使用Thread.interrupted()
的注释,稍微更改了代码以反映我的意思。谢谢,谢谢。实际上我更喜欢使用原子布尔。更改代码以反映这一点。在某些情况下,volatile可能会影响性能,特别是对于频繁访问。一般来说,volatile是一种更便宜的方法。原子变量只是有多一点灵活性。。。不要担心这么小的性能影响。它将缩短您的时间,并且对整个应用程序的影响可以忽略不计。您需要担心的是I/O操作和TCP连接。这是真的,在本例中无关紧要
记住当与static
一起使用时,volatile
会成为一个问题,并且有很多线程访问它。cleanUp()
应该位于finally
块中,除非您希望在发生意外异常时保持数据库连接打开。
ThreadPoolExecutor executor = new ....;
executor.execute(new Worker());
// some lines else later
executor.shutdownNow(); // shutdown() doesn't interrupt?