ScheduledThreadPoolExecutor afterExecute 的 runnable.toString 不同

ScheduledThreadPoolExecutor afterExecute's runnable.toString is different

我对 ThreadPoolExecutor 比较陌生。我正在查看是否可以在 executed 之前和 afterExecute.

中跟踪可运行对象

通过使用 afterExecute(Runnable t, Throwable t) 获得 runnable.toString()。现在,我意识到我可以将一个 Log 放入 runnable 本身......但我很好奇这种方法会产生什么。

对于 ThreadPoolExecutor,工作正常,runnable.toStringexecute(runnable) 之前和 afterExecute().

中是相同的

但是! ScheduledThreadPoolExecutor 不同。它的 afterExecute 的 runnable.toString 完全不同 .

例如执行前:my.pkg.name@abc,执行后: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);
}

ScheduledThreadPoolExecutor 在内部维护了一堆,以便根据计划轻松地添加和检索提交的任务(即,下一个需要在堆顶部执行的任务)。

为了帮助访问这个堆,ScheduledThreadPoolExecutor 的实现装饰了 ​​RunnableCallable 实例,你 schedule 使用一个自定义实现来描述它在堆中的位置, 除其他事项外。那就是您在日志中看到的 ScheduledFutureTask。请注意,这是一个实现细节(它是一个 private class),您不应该依赖它。