目录

线程的创建

目录

陈述

有四种方式来创建线程,建议还是这样说以体现知识的广度。

  • 继承 Thread ,重写 run 方法,调用 start 方法(开启一个线程等待CPU调度,不保证立即运行)
  • 实现 Runnable 接口,重写 run 方法,new Thread 传入对象,借助 Thread 代理对象调用 start 方法
  • 实现 Callable 接口,JUC 里面的
  • 通过线程池创建

在本质上,创建线程只有一种方式,就是构造一个 Thread 类(其子类其实也可以认为是一个 Thread 类)1。而构造 Thread 类又有两种方式,一种是继承 Thread 类,一种是实现 Runnable接口。其最终都会创建 Thread 类(或其子类)的对象。再来看实现 Callable ,结合 Future 和 FutureTask 的方式。可以发现,其最终也是通过 new Thread(task) 的方式构造 Thread 类。最后,在线程池中,我们其实是把创建和管理线程的任务都交给了线程池。而创建线程是通过线程工厂类 DefaultThreadFactory 来创建的(也可以自定义工厂类),它最后还是通过 new Thread() 的方式来创建线程的。

验证

import java.util.concurrent.*;

public class ThreadCreateTeset {

  public static void main(String[] args) {
    // 1 extend Thread
    Thread thread1 = new Thread1();
    thread1.start();
    // 2 implements Runnable
    Thread thread2 = new Thread(new Thread2());
    thread2.start();
    // 3 implements Callable
    FutureTask<Integer> task = new FutureTask<>(new Thread3());
    Thread thread3 = new Thread(task);
    thread3.start();
    try {
      System.out.println(task.get());
    } catch (InterruptedException | ExecutionException e) {
      e.printStackTrace();
    }
    // 4 线程池
    ExecutorService pool = Executors.newFixedThreadPool(3);
    for (int i = 0; i < 3; i++) {
      pool.execute(thread2);
    }
    pool.shutdown();
  }

}

输出:

Thread-1 running...
1
pool-1-thread-1 running...
pool-1-thread-2 running...
pool-1-thread-3 running...
Thread-0 running...
Thread-1 running...
pool-1-thread-2 running...
pool-1-thread-3 running...
pool-1-thread-1 running...
Thread-0 running...

关于线程池的类图:

https://cdn.jsdelivr.net/gh/dfface/img0@master/2022/04-25-BouGqh.jpg