https://blog.csdn.net/Hellowenpan/article/details/115869474

  1. 将 Callable 或 Runnable 封装为一个FutureTask
  1. 将要执行的任务 FutureTask包装成一个worker节点,并且执行该任务(如果条件成立)。

image.png

一般我们都是通过 ThreadPoolExecutor.submit() 的方式将任务提交到线程池!

一个任务提交到线程池,大致分为三步:

  1. 将任务封装为 FutureTask
  2. 执行 execute
  3. 返回

A)、封装为 FutureTask

  1. submit 方法

可以看到 submit 方法有三个重载方法,该方法可以提交 Runnable 和 Callable 类型的任务。不管是提交的 Runnable 还是 Callable 类型的任务,都会在该方法中被封装为一个 FutureTask 然后提交到线程池中。


public abstract class AbstractExecutorService implements ExecutorService {
  
    // submit 重载方法1
  	public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        // ①、提交到线程池的时候会将 Runnable 任务封装为一个 FutureTask
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        // ②、执行。后面详细介绍
        execute(ftask);
        // ③、返回 Future ,可通过 Future.get到线程执行后的返回值(这里的返回值就是 null )
        return ftask;
    }
  
		// submit 重载方法2
    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null) throw new NullPointerException();
        // ①、提交到线程池的时候会将 Runnable 任务封装为一个 FutureTask
        RunnableFuture<T> ftask = newTaskFor(task, result);
        // ②、执行。后面详细介绍
        execute(ftask);
        // ③、返回 Future ,可通过 Future.get到线程执行后的返回值(这里的返回值就是传进来的 result )
        return ftask;
    }
  
		// submit 重载方法3
    public <T> Future<T> submit(Callable<T> task) {
        if ①、(task == null) throw new NullPointerException();
        // 提交到线程池的时候会将 Callable 任务封装为一个 FutureTask
        RunnableFuture<T> ftask = newTaskFor(task);
      	// ②、执行。后面详细介绍
        execute(ftask);
        // ③、返回 Future ,可通过 Future.get到线程执行后的返回值
        return ftask;
    }
}

2、将 Callable 或 Runnable 封装为一个FutureTask

不管是提交的 Runnable 还是 Callable 类型的任务,都会在该方法中被封装为一个 FutureTask