gpt4 book ai didi

java - 为什么可暂停线程池执行器关闭后,Runnable 仍然在执行器中执行?

转载 作者:行者123 更新时间:2023-12-02 12:47:36 24 4
gpt4 key购买 nike

我有一个可暂停的线程池执行器实现,就像 ThreadPoolExecutor 类的文档中一样。我有一个简单的测试,可以执行以下操作:

class PausableThreadPoolExecutor extends ThreadPoolExecutor {
public static PausableThreadPoolExecutor newSingleThreadExecutor() {
return new PausableThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}

/** isPaused */
private boolean isPaused;

/** pauseLock */
private ReentrantLock pauseLock = new ReentrantLock();

/** unpaused */
private Condition unpaused = this.pauseLock.newCondition();

public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}

@Override
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
this.pauseLock.lock();
try {
while (this.isPaused) {
this.unpaused.await();
}
} catch (InterruptedException ie) {
t.interrupt();
} finally {
this.pauseLock.unlock();
}
}

public void pause() {
this.pauseLock.lock();
try {
this.isPaused = true;
} finally {
this.pauseLock.unlock();
}
}

public void resume() {
this.pauseLock.lock();
try {
this.isPaused = false;
this.unpaused.signalAll();
} finally {
this.pauseLock.unlock();
}
}

public static void main(String[] args) {
PausableThreadPoolExecutor p = PausableThreadPoolExecutor.newSingleThreadExecutor();
p.pause();
p.execute(new Runnable() {

public void run() {
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
System.out.println(ste);
}
}
});
p.shutdownNow();
}
}

有趣的是,对 shutdownNow 的调用将导致 Runnable 运行。这是正常的吗?据我了解,shutDownNow 将尝试通过中断来停止正在执行的任务。但中断似乎唤醒了任务并执行它。有人能解释一下吗?

最佳答案

Interestingly the call to shutDownNow will cause the Runnable to run. Is this normal?

不确定它是否“正常”,但考虑到您的代码,这肯定是预期的。在您的 beforeExecute(...) 方法中,我看到以下内容:

    this.pauseLock.lock();
try {
while (this.isPaused) {
this.unpaused.await();
}
} catch (InterruptedException ie) {
t.interrupt();
} finally {
this.pauseLock.unlock();
}

作业将等待 isPaused boolean 值设置为 false。但是,如果作业被中断,this.unpaused.await() 将抛出 InterruptedException,从而打破 while 循环,线程将被中断。重新中断,这始终是一个好的模式,beforeExecute() 返回,并且允许执行作业。除非您有特定的代码来处理中断,否则中断线程不会杀死它。

如果您想在作业被中断时停止作业,那么当您看到作业被中断时,可以在 beforeExecute() 处理程序中抛出 RuntimeException:

} catch (InterruptedException ie) {
t.interrupt();
throw new RuntimeException("Thread was interrupted so don't run");

更简洁的方法可能是检查 run() 方法中是否被中断,然后退出:

public void run() {
if (Thread.currentThread().isInterrupted()) {
return;
}
...

关于java - 为什么可暂停线程池执行器关闭后,Runnable 仍然在执行器中执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44699259/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com