TTL-agent修饰后的ScheduledThreadPoolExecutor的调度任务在取消时,无法从workQueue中清除
robin-g-20230331 opened this issue · 2 comments
robin-g-20230331 commented
问题及其示例代码
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);
调度线程池设置了任务cancel
后清理队列的策略;但是任务取消后,队列任务并没有清除。
原因
在调度池里,任务都会被修饰为ScheduledFutureTask
放入队列,并返回ScheduledFutureTask
类型的future
,ScheduledFutureTask
在cancel
时,会调用ThreadPoolExecutor
的remove
方法,而TTL Agent
会将ScheduledFutureTask
重新装饰为TtlRunnable
。
ScheduledThreadPoolExecutor
中的队列清理方法中的定位逻辑如下,可以明显看到,该方法只会返回-1
。
并且,如果这个队列很长,会导致性能非常差。
修复建议
remove
方法不增强。或者判断下类型,如果是ScheduledFutureTask
类型,就不增强。
oldratlee commented
@robin-g-20230331 收到。我先理解确认一下问题,然后再想想如何修改好。
oldratlee commented
- reproduce the bug at commit 4b7771f
- more info see the related failed CI jobs
- fix the bug at commit 8ca0f9a
- your solution is teriffic: 👍
- bypass the enhancement when the runnable argument is type
ScheduledFutureTask
- released in
v2.14.4
:
https://github.com/alibaba/transmittable-thread-local/releases/tag/v2.14.4
Thanks for your professional issue and solution 💗 @robin-g-20230331