粗看-线程池ThreadPoolExecutor

98 阅读1分钟

概述

线程池的基本组成:n个线程(线程池),n个任务(任务队列)

线程

线程的存储

线程池一定包含线程,在ThreadPoolExecutor中的体现为内部类worker;线程和worker之间的关系就是一对一;并且是AQS的实现,还是一个Runnable image.png ThreadPoolExecutor需要一堆线程,线程存放在一个HashSet的属性中workers image.png

线程的创建

在worker的构造方法中使用ThreadFactory的newThread方法获取线程; image.png image.png 具体的创建逻辑在实现ThreadFactory接口的类中;eg: DefaultThreadFactory image.png 而worker是在addWorker方法中创建,并且执行线程 image.png 代码第一行retry:参考 www.cnblogs.com/captainad/p…

线程的执行

线程池的执行都是实现Executor接口的execute方法;ThreadPoolExecutor继承关系顶层就是Executor,并且实现了execute方法,execute方法调用的addWorker方法,所以线程真正执行就是addWorker方法中使用Thread的start方法 image.png

任务和线程怎么组装的?

线程创建时就已经和任务绑定,但run方法中可以调用其他Runnable的run方法(或者自定义方法)

 public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("线程创建时就已经和任务绑定");
        });
        thread.start();
    }

ThreadPoolExecutor的做法如下

  1. ThreadPoolExecutor的worker包含了一个任务(这个任务是从一个任务队列中取的)
  2. 而worker本身也是一个任务Runnable
  3. 当线程执行worker的run方法时,worker的run方法调用自身的Runnable的run方法 伪代码如下
/**
 * worker
 */
public class Worker implements Runnable {
    //真正的任务
    Runnable task;

    public Worker(Runnable runnable) {
        this.task = runnable;
    }

    public static void main(String[] args) {
        Thread thread = new Thread(new Worker(() -> {
            System.out.println("task的run方法");
        }));
        thread.start();
    }

    @Override
    public void run() {
        System.out.println("Worker的run方法");
        runWorker();
    }

    private void runWorker() {
        this.task.run();
    }
}

任务