Executor框架维护着自己的Worker池,它们注意到了线程。那么,为什么我们必须传递Thread / Runnable作为参数。为什么没有简单的Task接口?
ExecutorService executorService = Executors.newFixedThreadPool(3); // 3 worker thread
executorService.execute(new Thread()); // why thread? Nobody is going to use this as thread?
我问这个是因为ThreadPoolExecutor在内部使用传递线程的 run 方法。
请参阅以下代码摘录:ThreadPoolExecutor:
final void runWorker(Worker w) {
Runnable task = w.firstTask;
w.firstTask = null;
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
clearInterruptsForTaskRun();
try {
beforeExecute(w.thread, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
如果我在这里遗漏任何重要信息,请告诉我。
答案 0 :(得分:2)
Executor#execute(Runnable)
接受任何Runnable
界面,而Thread
也会实施Runnable
,因此它是execute()
方法的有效参数。
The Executor Interface
对execute
说了什么?
Executor界面提供了一种方法Runnable
,旨在替代常见的线程创建习惯用法。如果r是Executor
对象,并且e是(new Thread(r)).start();
对象,则可以替换
e.execute(r);
与
(new Thread(new Thread())).start();
在你的情况下,内部变为:
{{1}}
答案 1 :(得分:1)
Runnable
不是线程。它只是一个定义run方法的接口。调用实现类的run方法并不是在新线程中运行它,只是在你已经在的线程中调用它,就像任何方法调用一样。基本上,Runnable
正是您建议的Task
界面。