我对ThreadPoolExecutor
相对较新。我是否可以在执行和 afterExecute 之前跟踪runnable。
使用runnable.toString()
获取afterExecute(Runnable t, Throwable t)
。现在,我意识到我可以将一个Log放入runnable本身...但我很好奇这个方法会产生什么。
对于ThreadPoolExecutor
,工作正常,runnable.toString
在execute(runnable)
之前和afterExecute()
之前相同。
然而! ScheduledThreadPoolExecutor
是不同的。它的 afterExecute的runnable.toString非常不同。
例如,之前:my.pkg.name@abc
,afterExecute:java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@zxc
甚至pkg名称都不一样。 这是为什么?
private MyThreadPool() {
threadPool = new ThreadPoolExecutor(NUMBER_OF_CORES, MAX_CORES,
KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, workQueue) {
@Override
public void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
Log.d(TAG, "ThreadOps onDone: " + r.toString());
// (A) will return same --> mypkgname@abc
}
};
threadPool.setRejectedExecutionHandler(rejectedHandler);
scheduledThreadPool = new ScheduledThreadPoolExecutor(NUMBER_OF_CORES) {
@Override
public void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
Log.d(TAG, "ThreadOps onDelayDone: " + r.toString());
// (D) does not return same?
// I am expecting --> mypkgname@qwe , but get...
// java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@zxc
}
};
scheduledThreadPool.setRejectedExecutionHandler(rejectedHandler);
}
public void execute(Runnable runnable) {
Log.d(TAG, "ThreadOps exe: " + runnable.toString());
// (A) lets say toString --> mypkgname@abc
threadPool.execute(runnable);
}
public void delayExecute(Runnable runnable, long delayms) {
Log.d(TAG, "ThreadOps exe @" + delayms + ": " + runnable.toString());
// (D) lets say toString --> mypkgname@qwe
scheduledThreadPool.schedule(runnable, delayms, TimeUnit.MILLISECONDS);
}
答案 0 :(得分:1)
ScheduledThreadPoolExecutor
在内部维护着一堆排序,可以根据计划安排的任务轻松添加和检索提交的任务(即需要在堆顶部执行的任务)。
为帮助访问此堆,ScheduledThreadPoolExecutor
的实现使用描述其在堆中的位置的自定义实现来装饰Runnable
或Callable
个实例schedule
其他事情。这是您在日志中看到的ScheduledFutureTask
。请注意,这是一个实施细节(它是private
类),您不应该依赖它。