Java ExecutorService-创建新线程但不启动它

Java ExecutorService-创建新线程但不启动它,java,multithreading,executorservice,Java,Multithreading,Executorservice,我在阅读《Java 8完整参考》一书的ExecutorService部分时,遇到了下面的代码片段 下面的代码片段解释了ExecutorService的工作原理 // A simple example that uses an Executor. import java.util.concurrent.*; class SimpExec { public static void main(String args[]) { CountDownLatch cdl = ne

我在阅读《Java 8完整参考》一书的
ExecutorService
部分时,遇到了下面的代码片段

下面的代码片段解释了
ExecutorService
的工作原理

// A simple example that uses an Executor.

import java.util.concurrent.*;

class SimpExec {

    public static void main(String args[]) {
        CountDownLatch cdl = new CountDownLatch(5);
        CountDownLatch cdl2 = new CountDownLatch(5);
        CountDownLatch cdl3 = new CountDownLatch(5);
        CountDownLatch cdl4 = new CountDownLatch(5);
        ExecutorService es = Executors.newFixedThreadPool(2);
        System.out.println("Starting");
        // Start the threads.
        es.execute(new MyThread(cdl, "A"));
        es.execute(new MyThread(cdl2, "B"));
        es.execute(new MyThread(cdl3, "C"));
        es.execute(new MyThread(cdl4, "D"));
        try {
            cdl.await();
            cdl2.await();
            cdl3.await();
            cdl4.await();
        } catch (InterruptedException exc) {
            System.out.println(exc);
        }
        es.shutdown();
        System.out.println("Done");
    }
}

class MyThread implements Runnable {

    String name;
    CountDownLatch latch;

    MyThread(CountDownLatch c, String n) {
        latch = c;
        name = n;
        new Thread(this);
    }

    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(name + ": " + i);
            latch.countDown();
        }
    }
}
//一个使用执行器的简单示例。
导入java.util.concurrent.*;
SimpExec类{
公共静态void main(字符串参数[]){
CountDownLatch cdl=新的CountDownLatch(5);
CountDownLatch cdl2=新的CountDownLatch(5);
CountDownLatch cdl3=新的CountDownLatch(5);
倒计时锁存器cdl4=新倒计时锁存器(5);
Executors服务es=Executors.newFixedThreadPool(2);
System.out.println(“启动”);
//启动线程。
执行(新神话阅读(cdl,“A”);
执行(新的MyThread(cdl2,“B”));
执行(新的MyThread(cdl3,“C”);
执行(新的MyThread(cdl4,“D”);
试一试{
cdl.wait();
cdl2.wait();
cdl3.await();
cdl4.wait();
}捕获(中断异常exc){
系统输出打印项次(exc);
}
es.shutdown();
系统输出打印项次(“完成”);
}
}
类MyThread实现可运行{
字符串名;
倒计时闩锁;
MyThread(倒计时锁存器c,字符串n){
闩锁=c;
name=n;
新线程(本);
}
公开募捐{
对于(int i=0;i<5;i++){
System.out.println(name+“:”+i);
倒计时();
}
}
}
我无法理解的是类
MyThread
的构造函数中的最后一行

MyThread
的构造函数使用

新线程(此)

但是,这个新创建的线程永远不会通过调用
start()
方法来启动。另外,根据我的理解,
ExecutorService
创建并管理自己的线程来运行我们的
runnable
任务。那么,在这种情况下,为什么要创建这个
线程
对象?

这一行:

new Thread(this);
对代码的执行没有影响,您可以毫无问题地删除

执行器将创建自己的线程以执行代码

您可以通过以下方式验证此行代码是否生效:

  • 从代码中删除该行(将得到相同的结果)
  • 给线程命名并调试新线程(这个“T:+n”)您将看到堆栈中没有出现具有此名称的线程
  • 您可以检查ThreadPoolExecutor的源代码,并验证方法
    private boolean addWorker(Runnable firstTask,boolean core)
    是否正在根据您作为参数提供的Runnable创建新的worker,以及它们是否在创建新的worker
  • --


    (a) 你提到的那行是不可操作的,所以把它去掉。(b) 为什么要调用
    Runnable
    MyThread
    ,而不是,比如说,
    MyRunnable
    ?@assylias(a)我很困惑,那么为什么这一行甚至是示例代码的一部分。(b) 这是书中的示例代码,不是我的代码;)(a) 只有作者知道(b)我理解——我只是说这让我质疑书的质量。但我还没有读过那本书,所以我不知道。谢谢你澄清我的困惑!
    w = new Worker(firstTask);
    final Thread t = w.thread;