【问题标题】:Why Tasks in Executor Framework are Threads为什么 Executor Framework 中的任务是线程
【发布时间】:2014-11-01 23:28:46
【问题描述】:

Executor 框架维护自己的工人池,这些工人池只是线程。然后,为什么我们必须传递 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);
        }
    }

如果我在这里遗漏了什么重要的东西,请告诉我。

【问题讨论】:

    标签: java multithreading threadpool runnable executorservice


    【解决方案1】:

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

    【讨论】:

    • 好吧 Gandaliter Executor 没有必要总是使用调用者线程处理任务。检查下面来自 Oracle 文档的 sn-p ------------“更典型的是,任务在调用者线程以外的某个线程中执行。执行者下面为每个任务生成一个新线程。”类 ThreadPerTaskExecutor 实现 Executor { public void execute(Runnable r) { new Thread(r).start(); } }
    • 是的,这些接口的全部意义在于它们为您处理线程,因此您可以只使用简单的 Runnables,它们对线程本身一无所知。当然,Executor 在不同的线程中运行它们(通常)。抱歉,如果不清楚。
    【解决方案2】:

    Executor#execute(Runnable) 接受任何Runnable 接口,Thread 也实现了Runnable,因此它是execute() 方法的有效参数。

    Oracle documentationThe Executor Interface 有何评论?

    Executor 接口提供了一个单一的方法execute,旨在替代常见的线程创建习惯用法。如果 r 是 Runnable 对象,并且 e 是 Executor 对象,则可以替换

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

    e.execute(r);
    

    在您的内部情况下,它变为:

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

    Read more...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-16
      • 1970-01-01
      • 2011-07-12
      • 1970-01-01
      • 2020-12-12
      • 1970-01-01
      • 2015-01-29
      • 1970-01-01
      相关资源
      最近更新 更多