alibaba / transmittable-thread-local

📌 a missing Java std lib(simple & 0-dependency) for framework/middleware, provide an enhanced InheritableThreadLocal that transmits values between threads even using thread pooling components.
https://github.com/alibaba/transmittable-thread-local
Apache License 2.0
7.59k stars 1.69k forks source link

TTL-agent修饰后的ScheduledThreadPoolExecutor的调度任务在取消时,无法从workQueue中清除 #547

Closed robin-g-20230331 closed 9 months ago

robin-g-20230331 commented 1 year ago

问题及其示例代码

ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);
scheduledThreadPoolExecutor.setRemoveOnCancelPolicy(true);
Future<?> future = scheduledThreadPoolExecutor.schedule(new Runnable() {
    @Override
    public void run() {
        // do something
    }
}, 100, TimeUnit.SECONDS);
future.cancel(false);
image

调度线程池设置了任务cancel后清理队列的策略;但是任务取消后,队列任务并没有清除。

原因

在调度池里,任务都会被修饰为ScheduledFutureTask放入队列,并返回ScheduledFutureTask类型的futureScheduledFutureTaskcancel时,会调用ThreadPoolExecutorremove方法,而TTL Agent会将ScheduledFutureTask重新装饰为TtlRunnable

ScheduledThreadPoolExecutor中的队列清理方法中的定位逻辑如下,可以明显看到,该方法只会返回-1

image

并且,如果这个队列很长,会导致性能非常差。

修复建议

remove方法不增强。或者判断下类型,如果是ScheduledFutureTask类型,就不增强。

oldratlee commented 1 year ago

@robin-g-20230331 收到。我先理解确认一下问题,然后再想想如何修改好。

oldratlee commented 9 months ago

@robin-g-20230331


Thanks for your professional issue and solution 💗 @robin-g-20230331