为什么Executor Framework中的任务是线程

时间:2014-09-08 17:04:56

标签: java multithreading threadpool runnable executorservice

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);
        }
    }

如果我在这里遗漏任何重要信息,请告诉我。

2 个答案:

答案 0 :(得分:2)

Executor#execute(Runnable)接受任何Runnable界面,而Thread也会实施Runnable,因此它是execute()方法的有效参数。

The Executor Interfaceexecute说了什么?

Executor界面提供了一种方法Runnable,旨在替代常见的线程创建习惯用法。如果r是Executor对象,并且e是(new Thread(r)).start(); 对象,则可以替换

e.execute(r);

(new Thread(new Thread())).start();

在你的情况下,内部变为:

{{1}}

Oracle documentation

答案 1 :(得分:1)

Runnable不是线程。它只是一个定义run方法的接口。调用实现类的run方法并不是在新线程中运行它,只是在你已经在的线程中调用它,就像任何方法调用一样。基本上,Runnable正是您建议的Task界面。