java - 阻塞在未来的线程会发生什么情况,相应的任务已被丢弃?

标签 java multithreading threadpoolexecutor

我正在使用 ExecutorService 在线程池上执行一些计算:

@Override
public double predict(IModelInputData<EXTRACTER> modelInputData) throws PredictionFailureException {
    try {
        return threadPool.submit(() -> regressor.predict(modelInputData)).get();
    } catch (InterruptedException|ExecutionException e) {
        throw new PredictionFailureException("Error during prediction", e);
    }
}

执行器服务 threadPool 已使用有界阻塞队列和自定义策略创建:

private static class DiscardOldestWithWarningPolicy extends ThreadPoolExecutor.DiscardOldestPolicy {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        super.rejectedExecution(r, e);
        LOG.warn("Discarded the oldest prediction task (too many tasks in the queue)");
    }
}

我做了一个测试以确保这个警告确实被记录了,它确实被记录了,但是我非常不确定在 threadPool.submit(...).get()< 上阻塞的线程会发生什么 当相应的任务被丢弃时。在我看来,它们一直处于阻塞状态,但这没有多大意义。我希望看到的行为是抛出异常以中断线程,但我还没有看到任何异常。

我错过了什么吗?

最佳答案

是的,看起来内置的 DiscardOldestPolicy 只是将最旧的丢弃在地板上。问题是 ThreadPoolExecutor 持有一个 Runnable,并且无法知道如何处理它。您可以实现自己的处理程序,它对任务做一些有用的事情(对 Runnable 的类型做出假设)。

类似于:

    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        if (!e.isShutdown()) {
            Runnable old = e.getQueue().poll();
            if(old instanceof Future<?>) {
                ((Future<?>)old).cancel(true);
            }
            e.execute(r);
        }
    }

关于java - 阻塞在未来的线程会发生什么情况,相应的任务已被丢弃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34547435/

相关文章:

java - 如何为 @Async 方法使用自定义执行器?

java - 哪里可以找到 `android.annotation.Nullable`

java - 删除 LinkedList 中的重复项

java - 如何检查 PrintStream 是否打开而不进行打印

java - Java 中的进程与线程

java - ThreadPoolExecutor 中的 allowCoreThreadTimeout( ) 有什么用?

java - Apache Camel 多部分路线

java - 对象 vs byte[0] 作为锁

java - 这是在 Java 中创建锁的可接受方式吗?

java - LinkedBlockingQueue put 与 offer