jdk-Executor线程池源码学习

什么是线程?

一个应用程序为一个进程(也有多个的),一个进程拥有至少1个线程,线程是这个进程所私有的,当进程结束时,线程会随着结束。如下图

97dde6ff717e5faab723e9da73b0931c.png

当然更有一些内存相关的,这里不再过多深入,仅了解基础,不懂的同学自行搜索。

线程有哪些生命状态,怎么切换的?

NEW,新建

RUNNABLE,运行

BLOCKED,阻塞

WAITING,等待

TIMED_WAITING,超时等待

TERMINATED,终结

a77538e0e2c1ac0c26f5152bb176ac3a.png

注意:java原生包不支持协程,需要支持可以引入第三方的quasar

java线程池有哪些?

线程池的主要作用是用来管理线程的一个容器,通过这个可以减少线程被无限制的创建和释放,导致系统资源无法很好管控,通过线程池可以通过分配、调优以及监控。

FixedThreadPool:固定大小的线程池,创建时指定线程数量,任务队列为无界队列。

  1. CachedThreadPool:缓存线程池,线程数量不固定,会根据需要自动创建新线程,空闲线程会被保留60秒,任务队列为SynchronousQueue。

  2. ScheduledThreadPool:定时器线程池,支持延时执行和定时周期执行任务。

  3. SingleThreadExecutor:单线程线程池,只有一个线程执行任务,任务队列为无界队列。

  4. WorkStealingPool:工作窃取线程池,每个线程都有自己的任务队列,线程可以从其他线程的任务队列中窃取任务执行。

线程池的基本使用

package com.executor;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author: csh
 * @Date: 2023/3/6 23:02
 * @Description:固定大小的线程池,线程数一旦达到最大值,新任务就会在等待队列中等待。适用于预先知道任务数量的情况。
 */
public class FixedThreadPoolStudy {

    public static void main(String[] args) {
        // 创建一个包含5个线程的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        // 提交10个任务
        for (int i = 1; i <= 10; i++) {
            executorService.execute(new Task(i));
        }
        // 关闭线程池
        executorService.shutdown();
    }
    static class Task implements Runnable {
        private int taskId;
        public Task(int taskId) {
            this.taskId = taskId;
        }
        @Override
        public void run() {
            System.out.println("任务" + taskId + "开始执行,当前线程名为" + Thread.currentThread().getName());
            try {
                // 模拟任务执行的耗时
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("任务" + taskId + "执行完毕,当前线程名为" + Thread.currentThread().getName());
        }
    }
}

运行结果

任务1开始执行,当前线程名为pool-1-thread-1
任务2开始执行,当前线程名为pool-1-thread-2
任务3开始执行,当前线程名为pool-1-thread-3
任务4开始执行,当前线程名为pool-1-thread-4
任务5开始执行,当前线程名为pool-1-thread-5
任务3执行完毕,当前线程名为pool-1-thread-3
任务1执行完毕,当前线程名为pool-1-thread-1
任务7开始执行,当前线程名为pool-1-thread-1
任务2执行完毕,当前线程名为pool-1-thread-2
任务8开始执行,当前线程名为pool-1-thread-2
任务4执行完毕,当前线程名为pool-1-thread-4
任务9开始执行,当前线程名为pool-1-thread-4
任务5执行完毕,当前线程名为pool-1-thread-5
任务10开始执行,当前线程名为pool-1-thread-5
任务6开始执行,当前线程名为pool-1-thread-3
任务9执行完毕,当前线程名为pool-1-thread-4
任务10执行完毕,当前线程名为pool-1-thread-5
任务8执行完毕,当前线程名为pool-1-thread-2
任务7执行完毕,当前线程名为pool-1-thread-1
任务6执行完毕,当前线程名为pool-1-thread-3
package com.executor;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author: csh
 * @Date: 2023/3/6 23:02
 * @Description:固定大小的线程池,线程数一旦达到最大值,新任务就会在等待队列中等待。适用于预先知道任务数量的情况。
 */
public class FixedThreadPoolStudy {

    public static void main(String[] args) {
        // 创建一个包含5个线程的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        // 提交10个任务
        for (int i = 1; i <= 10; i++) {
            executorService.execute(new Task(i));
        }
        // 关闭线程池
        executorService.shutdown();
    }
    static class Task implements Runnable {
        private int taskId;
        public Task(int taskId) {
            this.taskId = taskId;
        }
        @Override
        public void run() {
            System.out.println("任务" + taskId + "开始执行,当前线程名为" + Thread.currentThread().getName());
            try {
                // 模拟任务执行的耗时
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("任务" + taskId + "执行完毕,当前线程名为" + Thread.currentThread().getName());
        }
    }
}

结果

任务1开始执行,当前线程名为pool-1-thread-1
任务2开始执行,当前线程名为pool-1-thread-2
任务3开始执行,当前线程名为pool-1-thread-3
任务4开始执行,当前线程名为pool-1-thread-4
任务5开始执行,当前线程名为pool-1-thread-5
任务3执行完毕,当前线程名为pool-1-thread-3
任务1执行完毕,当前线程名为pool-1-thread-1
任务7开始执行,当前线程名为pool-1-thread-1
任务6开始执行,当前线程名为pool-1-thread-3
任务2执行完毕,当前线程名为pool-1-thread-2
任务8开始执行,当前线程名为pool-1-thread-2
任务4执行完毕,当前线程名为pool-1-thread-4
任务5执行完毕,当前线程名为pool-1-thread-5
任务9开始执行,当前线程名为pool-1-thread-4
任务10开始执行,当前线程名为pool-1-thread-5
任务6执行完毕,当前线程名为pool-1-thread-3
任务8执行完毕,当前线程名为pool-1-thread-2
任务9执行完毕,当前线程名为pool-1-thread-4
任务7执行完毕,当前线程名为pool-1-thread-1
任务10执行完毕,当前线程名为pool-1-thread-5
package com.executor;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 *
 * 功能描述: SingleThreadExecutor是一个只有一个线程的线程池,用于顺序执行任务。
 *
 * @param:
 * @return: 
 * @auther: csh
 * @date: 2023/3/6 11:09 下午
 */
public class SingleThreadExecutorStudy {
    public static void main(String[] args) {
        // 创建一个只有一个线程的线程池
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        // 提交10个任务
        for (int i = 1; i <= 10; i++) {
            executorService.execute(new Task(i));
        }
        // 关闭线程池
        executorService.shutdown();
    }
    static class Task implements Runnable {
        private int taskId;
        public Task(int taskId) {
            this.taskId = taskId;
        }
        @Override
        public void run() {
            System.out.println("任务" + taskId + "开始执行,当前线程名为" + Thread.currentThread().getName());
            try {
                // 模拟任务执行的耗时
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("任务" + taskId + "执行完毕,当前线程名为" + Thread.currentThread().getName());
        }
    }
}

结果 (可以看出下面只有一个线程在跑)

任务1开始执行,当前线程名为pool-1-thread-1
任务1执行完毕,当前线程名为pool-1-thread-1
任务2开始执行,当前线程名为pool-1-thread-1
任务2执行完毕,当前线程名为pool-1-thread-1
任务3开始执行,当前线程名为pool-1-thread-1
任务3执行完毕,当前线程名为pool-1-thread-1
任务4开始执行,当前线程名为pool-1-thread-1
任务4执行完毕,当前线程名为pool-1-thread-1
任务5开始执行,当前线程名为pool-1-thread-1
任务5执行完毕,当前线程名为pool-1-thread-1
任务6开始执行,当前线程名为pool-1-thread-1
任务6执行完毕,当前线程名为pool-1-thread-1
任务7开始执行,当前线程名为pool-1-thread-1
任务7执行完毕,当前线程名为pool-1-thread-1
任务8开始执行,当前线程名为pool-1-thread-1
任务8执行完毕,当前线程名为pool-1-thread-1
任务9开始执行,当前线程名为pool-1-thread-1
任务9执行完毕,当前线程名为pool-1-thread-1
任务10开始执行,当前线程名为pool-1-thread-1
任务10执行完毕,当前线程名为pool-1-thread-1
package com.executor;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
 *
 * 功能描述: ScheduledThreadPool是一个可以执行定时任务的线程池,可以实现延迟执行和周期执行。
 *
 * @param: 
 * @return: 
 * @auther: csh
 * @date: 2023/3/6 11:13 下午
 */
public class ScheduledThreadPoolStudy {
    public static void main(String[] args) {
        // 创建一个可以执行定时任务的线程池
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
        // 提交10个定时任务,每个任务延迟1秒后执行,每个任务执行周期为2秒
        for (int i = 1; i <= 10; i++) {
            scheduledExecutorService.scheduleAtFixedRate(new Task(i), 1, 2, TimeUnit.SECONDS);
        }
        // 关闭线程池
       // scheduledExecutorService.shutdown();
    }
    static class Task implements Runnable {
        private int taskId;
        public Task(int taskId) {
            this.taskId = taskId;
        }
        @Override
        public void run() {
            System.out.println("任务" + taskId + "开始执行,当前线程名为" + Thread.currentThread().getName());
            try {
                // 模拟任务执行的耗时
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("任务" + taskId + "执行完毕,当前线程名为" + Thread.currentThread().getName());
        }
    }
}

结果 可以看到 实现了周期性执行

任务4开始执行,当前线程名为pool-1-thread-2
任务10执行完毕,当前线程名为pool-1-thread-3
任务5开始执行,当前线程名为pool-1-thread-3
任务1执行完毕,当前线程名为pool-1-thread-1
任务6开始执行,当前线程名为pool-1-thread-1
任务2执行完毕,当前线程名为pool-1-thread-4
任务7开始执行,当前线程名为pool-1-thread-4
任务3执行完毕,当前线程名为pool-1-thread-5
任务8开始执行,当前线程名为pool-1-thread-5
任务4执行完毕,当前线程名为pool-1-thread-2
任务9开始执行,当前线程名为pool-1-thread-2
任务5执行完毕,当前线程名为pool-1-thread-3
任务10开始执行,当前线程名为pool-1-thread-3
任务6执行完毕,当前线程名为pool-1-thread-1
任务1开始执行,当前线程名为pool-1-thread-1
任务7执行完毕,当前线程名为pool-1-thread-4
任务2开始执行,当前线程名为pool-1-thread-4
任务8执行完毕,当前线程名为pool-1-thread-5
任务3开始执行,当前线程名为pool-1-thread-5
任务9执行完毕,当前线程名为pool-1-thread-2
任务4开始执行,当前线程名为pool-1-thread-2
任务10执行完毕,当前线程名为pool-1-thread-3
任务5开始执行,当前线程名为pool-1-thread-3
任务1执行完毕,当前线程名为pool-1-thread-1
任务6开始执行,当前线程名为pool-1-thread-1
任务2执行完毕,当前线程名为pool-1-thread-4
任务7开始执行,当前线程名为pool-1-thread-4
任务3执行完毕,当前线程名为pool-1-thread-5
任务8开始执行,当前线程名为pool-1-thread-5
任务4执行完毕,当前线程名为pool-1-thread-2
任务9开始执行,当前线程名为pool-1-thread-2
任务5执行完毕,当前线程名为pool-1-thread-3
任务10开始执行,当前线程名为pool-1-thread-3
任务6执行完毕,当前线程名为pool-1-thread-1
任务1开始执行,当前线程名为pool-1-thread-1
任务8执行完毕,当前线程名为pool-1-thread-5
任务2开始执行,当前线程名为pool-1-thread-5
任务7执行完毕,当前线程名为pool-1-thread-4
任务3开始执行,当前线程名为pool-1-thread-4
任务9执行完毕,当前线程名为pool-1-thread-2
任务10执行完毕,当前线程名为pool-1-thread-3
任务4开始执行,当前线程名为pool-1-thread-2
任务5开始执行,当前线程名为pool-1-thread-3
任务1执行完毕,当前线程名为pool-1-thread-1
任务6开始执行,当前线程名为pool-1-thread-1
任务2执行完毕,当前线程名为pool-1-thread-5
任务7开始执行,当前线程名为pool-1-thread-5
任务3执行完毕,当前线程名为pool-1-thread-4
任务8开始执行,当前线程名为pool-1-thread-4
任务4执行完毕,当前线程名为pool-1-thread-2
任务5执行完毕,当前线程名为pool-1-thread-3
任务9开始执行,当前线程名为pool-1-thread-3
任务10开始执行,当前线程名为pool-1-thread-2
任务6执行完毕,当前线程名为pool-1-thread-1
任务1开始执行,当前线程名为pool-1-thread-1
任务8执行完毕,当前线程名为pool-1-thread-4
任务2开始执行,当前线程名为pool-1-thread-4
任务7执行完毕,当前线程名为pool-1-thread-5
任务3开始执行,当前线程名为pool-1-thread-5
任务9执行完毕,当前线程名为pool-1-thread-3
任务10执行完毕,当前线程名为pool-1-thread-2
任务4开始执行,当前线程名为pool-1-thread-3
任务5开始执行,当前线程名为pool-1-thread-2
任务1执行完毕,当前线程名为pool-1-thread-1
任务6开始执行,当前线程名为pool-1-thread-1
任务3执行完毕,当前线程名为pool-1-thread-5
任务7开始执行,当前线程名为pool-1-thread-5
任务2执行完毕,当前线程名为pool-1-thread-4
任务8开始执行,当前线程名为pool-1-thread-4
任务4执行完毕,当前线程名为pool-1-thread-3
任务5执行完毕,当前线程名为pool-1-thread-2
任务9开始执行,当前线程名为pool-1-thread-3
任务10开始执行,当前线程名为pool-1-thread-2
任务6执行完毕,当前线程名为pool-1-thread-1
任务1开始执行,当前线程名为pool-1-thread-1
任务7执行完毕,当前线程名为pool-1-thread-5
任务2开始执行,当前线程名为pool-1-thread-5
任务8执行完毕,当前线程名为pool-1-thread-4
任务3开始执行,当前线程名为pool-1-thread-4
任务9执行完毕,当前线程名为pool-1-thread-3
任务4开始执行,当前线程名为pool-1-thread-3
任务10执行完毕,当前线程名为pool-1-thread-2
任务5开始执行,当前线程名为pool-1-thread-2
任务1执行完毕,当前线程名为pool-1-thread-1
任务6开始执行,当前线程名为pool-1-thread-1
任务2执行完毕,当前线程名为pool-1-thread-5
任务7开始执行,当前线程名为pool-1-thread-5
任务3执行完毕,当前线程名为pool-1-thread-4
任务8开始执行,当前线程名为pool-1-thread-4
任务4执行完毕,当前线程名为pool-1-thread-3
任务9开始执行,当前线程名为pool-1-thread-3
任务5执行完毕,当前线程名为pool-1-thread-2
任务10开始执行,当前线程名为pool-1-thread-2
任务6执行完毕,当前线程名为pool-1-thread-1
任务1开始执行,当前线程名为pool-1-thread-1
任务8执行完毕,当前线程名为pool-1-thread-4
任务7执行完毕,当前线程名为pool-1-thread-5
任务2开始执行,当前线程名为pool-1-thread-4
任务3开始执行,当前线程名为pool-1-thread-5
任务9执行完毕,当前线程名为pool-1-thread-3
任务4开始执行,当前线程名为pool-1-thread-3
任务10执行完毕,当前线程名为pool-1-thread-2
任务5开始执行,当前线程名为pool-1-thread-2
任务1执行完毕,当前线程名为pool-1-thread-1
任务6开始执行,当前线程名为pool-1-thread-1
任务3执行完毕,当前线程名为pool-1-thread-5
任务2执行完毕,当前线程名为pool-1-thread-4
任务7开始执行,当前线程名为pool-1-thread-5
任务8开始执行,当前线程名为pool-1-thread-4
任务4执行完毕,当前线程名为pool-1-thread-3
任务9开始执行,当前线程名为pool-1-thread-3
任务5执行完毕,当前线程名为pool-1-thread-2
任务10开始执行,当前线程名为pool-1-thread-2
package com.executor;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
 *
 * 功能描述: WorkStealingPool是一个基于工作窃取算法的线程池,用于提高多核CPU的利用率。
 *
 * @param:
 * @return: 
 * @auther: csh
 * @date: 2023/3/6 11:18 下午
 */
public class WorkStealingPoolStudy {
    public static void main(String[] args) {
        // 获取当前系统的CPU核心数
        int processors = Runtime.getRuntime().availableProcessors();
        // 创建一个基于工作窃取算法的线程池
        ExecutorService executorService = Executors.newWorkStealingPool(processors);
        // 提交10个任务
        for (int i = 1; i <= 1000; i++) {
            executorService.execute(new Task(i));
        }
        // 等待所有任务执行完毕
        try {
            executorService.awaitTermination(1, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 关闭线程池
        executorService.shutdown();
    }
    static class Task implements Runnable {
        private int taskId;
        public Task(int taskId) {
            this.taskId = taskId;
        }
        @Override
        public void run() {
            System.out.println("任务" + taskId + "开始执行,当前线程名为" + Thread.currentThread().getName());
            try {
                // 模拟任务执行的耗时
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("任务" + taskId + "执行完毕,当前线程名为" + Thread.currentThread().getName());
        }
    }
}

结果

任务8开始执行,当前线程名为ForkJoinPool-1-worker-0
任务4开始执行,当前线程名为ForkJoinPool-1-worker-4
任务5开始执行,当前线程名为ForkJoinPool-1-worker-5
任务2开始执行,当前线程名为ForkJoinPool-1-worker-2
任务3开始执行,当前线程名为ForkJoinPool-1-worker-3
任务6开始执行,当前线程名为ForkJoinPool-1-worker-6
任务1开始执行,当前线程名为ForkJoinPool-1-worker-1
任务7开始执行,当前线程名为ForkJoinPool-1-worker-7
任务8执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务1执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务2执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务5执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务12开始执行,当前线程名为ForkJoinPool-1-worker-5
任务4执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务13开始执行,当前线程名为ForkJoinPool-1-worker-4
任务7执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务14开始执行,当前线程名为ForkJoinPool-1-worker-7
任务11开始执行,当前线程名为ForkJoinPool-1-worker-2
任务3执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务6执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务9开始执行,当前线程名为ForkJoinPool-1-worker-0
任务10开始执行,当前线程名为ForkJoinPool-1-worker-1
任务16开始执行,当前线程名为ForkJoinPool-1-worker-6
任务15开始执行,当前线程名为ForkJoinPool-1-worker-3
任务12执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务10执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务18开始执行,当前线程名为ForkJoinPool-1-worker-1
任务15执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务19开始执行,当前线程名为ForkJoinPool-1-worker-3
任务13执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务20开始执行,当前线程名为ForkJoinPool-1-worker-4
任务9执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务21开始执行,当前线程名为ForkJoinPool-1-worker-0
任务11执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务22开始执行,当前线程名为ForkJoinPool-1-worker-2
任务14执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务23开始执行,当前线程名为ForkJoinPool-1-worker-7
任务16执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务24开始执行,当前线程名为ForkJoinPool-1-worker-6
任务17开始执行,当前线程名为ForkJoinPool-1-worker-5
任务19执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务23执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务24执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务25开始执行,当前线程名为ForkJoinPool-1-worker-3
任务26开始执行,当前线程名为ForkJoinPool-1-worker-7
任务17执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务20执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务27开始执行,当前线程名为ForkJoinPool-1-worker-6
任务22执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务29开始执行,当前线程名为ForkJoinPool-1-worker-4
任务30开始执行,当前线程名为ForkJoinPool-1-worker-2
任务28开始执行,当前线程名为ForkJoinPool-1-worker-5
任务18执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务21执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务31开始执行,当前线程名为ForkJoinPool-1-worker-1
任务32开始执行,当前线程名为ForkJoinPool-1-worker-0
任务26执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务29执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务30执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务33开始执行,当前线程名为ForkJoinPool-1-worker-7
任务31执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务27执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务25执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务28执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务38开始执行,当前线程名为ForkJoinPool-1-worker-3
任务37开始执行,当前线程名为ForkJoinPool-1-worker-6
任务36开始执行,当前线程名为ForkJoinPool-1-worker-1
任务35开始执行,当前线程名为ForkJoinPool-1-worker-4
任务34开始执行,当前线程名为ForkJoinPool-1-worker-2
任务39开始执行,当前线程名为ForkJoinPool-1-worker-5
任务32执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务40开始执行,当前线程名为ForkJoinPool-1-worker-0
任务34执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务41开始执行,当前线程名为ForkJoinPool-1-worker-2
任务39执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务42开始执行,当前线程名为ForkJoinPool-1-worker-5
任务35执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务43开始执行,当前线程名为ForkJoinPool-1-worker-4
任务36执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务44开始执行,当前线程名为ForkJoinPool-1-worker-1
任务33执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务38执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务45开始执行,当前线程名为ForkJoinPool-1-worker-3
任务46开始执行,当前线程名为ForkJoinPool-1-worker-7
任务37执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务47开始执行,当前线程名为ForkJoinPool-1-worker-6
任务40执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务48开始执行,当前线程名为ForkJoinPool-1-worker-0
任务44执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务49开始执行,当前线程名为ForkJoinPool-1-worker-1
任务42执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务43执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务45执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务41执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务52开始执行,当前线程名为ForkJoinPool-1-worker-3
任务51开始执行,当前线程名为ForkJoinPool-1-worker-4
任务50开始执行,当前线程名为ForkJoinPool-1-worker-5
任务53开始执行,当前线程名为ForkJoinPool-1-worker-2
任务47执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务54开始执行,当前线程名为ForkJoinPool-1-worker-6
任务46执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务48执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务55开始执行,当前线程名为ForkJoinPool-1-worker-7
任务56开始执行,当前线程名为ForkJoinPool-1-worker-0
任务49执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务57开始执行,当前线程名为ForkJoinPool-1-worker-1
任务51执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务58开始执行,当前线程名为ForkJoinPool-1-worker-4
任务52执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务59开始执行,当前线程名为ForkJoinPool-1-worker-3
任务53执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务60开始执行,当前线程名为ForkJoinPool-1-worker-2
任务56执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务54执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务61开始执行,当前线程名为ForkJoinPool-1-worker-0
任务55执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务63开始执行,当前线程名为ForkJoinPool-1-worker-7
任务50执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务64开始执行,当前线程名为ForkJoinPool-1-worker-5
任务62开始执行,当前线程名为ForkJoinPool-1-worker-6
任务57执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务62执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务64执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务60执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务63执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务59执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务61执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务67开始执行,当前线程名为ForkJoinPool-1-worker-2
任务58执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务68开始执行,当前线程名为ForkJoinPool-1-worker-6
任务71开始执行,当前线程名为ForkJoinPool-1-worker-0
任务72开始执行,当前线程名为ForkJoinPool-1-worker-4
任务69开始执行,当前线程名为ForkJoinPool-1-worker-7
任务70开始执行,当前线程名为ForkJoinPool-1-worker-3
任务66开始执行,当前线程名为ForkJoinPool-1-worker-5
任务65开始执行,当前线程名为ForkJoinPool-1-worker-1
任务67执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务66执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务65执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务70执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务72执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务68执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务71执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务69执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务79开始执行,当前线程名为ForkJoinPool-1-worker-0
任务78开始执行,当前线程名为ForkJoinPool-1-worker-6
任务77开始执行,当前线程名为ForkJoinPool-1-worker-4
任务76开始执行,当前线程名为ForkJoinPool-1-worker-3
任务75开始执行,当前线程名为ForkJoinPool-1-worker-1
任务74开始执行,当前线程名为ForkJoinPool-1-worker-5
任务73开始执行,当前线程名为ForkJoinPool-1-worker-2
任务80开始执行,当前线程名为ForkJoinPool-1-worker-7
任务75执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务79执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务73执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务76执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务84开始执行,当前线程名为ForkJoinPool-1-worker-3
任务78执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务82开始执行,当前线程名为ForkJoinPool-1-worker-0
任务81开始执行,当前线程名为ForkJoinPool-1-worker-1
任务85开始执行,当前线程名为ForkJoinPool-1-worker-6
任务83开始执行,当前线程名为ForkJoinPool-1-worker-2
任务80执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务86开始执行,当前线程名为ForkJoinPool-1-worker-7
任务74执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务77执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务87开始执行,当前线程名为ForkJoinPool-1-worker-5
任务88开始执行,当前线程名为ForkJoinPool-1-worker-4
任务82执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务84执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务89开始执行,当前线程名为ForkJoinPool-1-worker-3
任务81执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务85执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务86执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务90开始执行,当前线程名为ForkJoinPool-1-worker-1
任务83执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务92开始执行,当前线程名为ForkJoinPool-1-worker-2
任务91开始执行,当前线程名为ForkJoinPool-1-worker-0
任务93开始执行,当前线程名为ForkJoinPool-1-worker-6
任务94开始执行,当前线程名为ForkJoinPool-1-worker-7
任务88执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务95开始执行,当前线程名为ForkJoinPool-1-worker-4
任务87执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务96开始执行,当前线程名为ForkJoinPool-1-worker-5
任务92执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务94执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务98开始执行,当前线程名为ForkJoinPool-1-worker-7
任务95执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务99开始执行,当前线程名为ForkJoinPool-1-worker-4
任务97开始执行,当前线程名为ForkJoinPool-1-worker-2
任务89执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务100开始执行,当前线程名为ForkJoinPool-1-worker-3
任务91执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务101开始执行,当前线程名为ForkJoinPool-1-worker-0
任务93执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务102开始执行,当前线程名为ForkJoinPool-1-worker-6
任务90执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务103开始执行,当前线程名为ForkJoinPool-1-worker-1
任务96执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务104开始执行,当前线程名为ForkJoinPool-1-worker-5
任务97执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务104执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务101执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务100执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务105开始执行,当前线程名为ForkJoinPool-1-worker-2
任务99执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务107开始执行,当前线程名为ForkJoinPool-1-worker-4
任务108开始执行,当前线程名为ForkJoinPool-1-worker-5
任务98执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务109开始执行,当前线程名为ForkJoinPool-1-worker-7
任务102执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务111开始执行,当前线程名为ForkJoinPool-1-worker-6
任务103执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务110开始执行,当前线程名为ForkJoinPool-1-worker-0
任务106开始执行,当前线程名为ForkJoinPool-1-worker-3
任务112开始执行,当前线程名为ForkJoinPool-1-worker-1
任务110执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务112执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务113开始执行,当前线程名为ForkJoinPool-1-worker-0
任务107执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务114开始执行,当前线程名为ForkJoinPool-1-worker-1
任务115开始执行,当前线程名为ForkJoinPool-1-worker-4
任务105执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务111执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务109执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务108执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务106执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务119开始执行,当前线程名为ForkJoinPool-1-worker-5
任务118开始执行,当前线程名为ForkJoinPool-1-worker-7
任务117开始执行,当前线程名为ForkJoinPool-1-worker-6
任务116开始执行,当前线程名为ForkJoinPool-1-worker-2
任务120开始执行,当前线程名为ForkJoinPool-1-worker-3
任务114执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务121开始执行,当前线程名为ForkJoinPool-1-worker-1
任务113执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务115执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务122开始执行,当前线程名为ForkJoinPool-1-worker-4
任务123开始执行,当前线程名为ForkJoinPool-1-worker-0
任务116执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务118执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务124开始执行,当前线程名为ForkJoinPool-1-worker-2
任务125开始执行,当前线程名为ForkJoinPool-1-worker-7
任务119执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务120执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务117执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务126开始执行,当前线程名为ForkJoinPool-1-worker-5
任务128开始执行,当前线程名为ForkJoinPool-1-worker-6
任务127开始执行,当前线程名为ForkJoinPool-1-worker-3
任务125执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务129开始执行,当前线程名为ForkJoinPool-1-worker-7
任务123执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务130开始执行,当前线程名为ForkJoinPool-1-worker-0
任务121执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务124执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务122执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务133开始执行,当前线程名为ForkJoinPool-1-worker-4
任务132开始执行,当前线程名为ForkJoinPool-1-worker-2
任务131开始执行,当前线程名为ForkJoinPool-1-worker-1
任务128执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务127执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务126执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务135开始执行,当前线程名为ForkJoinPool-1-worker-3
任务134开始执行,当前线程名为ForkJoinPool-1-worker-6
任务136开始执行,当前线程名为ForkJoinPool-1-worker-5
任务129执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务132执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务130执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务131执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务133执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务137开始执行,当前线程名为ForkJoinPool-1-worker-7
任务138开始执行,当前线程名为ForkJoinPool-1-worker-2
任务141开始执行,当前线程名为ForkJoinPool-1-worker-4
任务139开始执行,当前线程名为ForkJoinPool-1-worker-0
任务140开始执行,当前线程名为ForkJoinPool-1-worker-1
任务134执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务135执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务136执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务143开始执行,当前线程名为ForkJoinPool-1-worker-3
任务144开始执行,当前线程名为ForkJoinPool-1-worker-5
任务142开始执行,当前线程名为ForkJoinPool-1-worker-6
任务137执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务141执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务145开始执行,当前线程名为ForkJoinPool-1-worker-7
任务138执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务146开始执行,当前线程名为ForkJoinPool-1-worker-4
任务139执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务147开始执行,当前线程名为ForkJoinPool-1-worker-2
任务148开始执行,当前线程名为ForkJoinPool-1-worker-0
任务140执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务149开始执行,当前线程名为ForkJoinPool-1-worker-1
任务143执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务142执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务150开始执行,当前线程名为ForkJoinPool-1-worker-3
任务151开始执行,当前线程名为ForkJoinPool-1-worker-6
任务144执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务152开始执行,当前线程名为ForkJoinPool-1-worker-5
任务145执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务153开始执行,当前线程名为ForkJoinPool-1-worker-7
任务148执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务149执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务154开始执行,当前线程名为ForkJoinPool-1-worker-0
任务155开始执行,当前线程名为ForkJoinPool-1-worker-1
任务146执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务147执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务157开始执行,当前线程名为ForkJoinPool-1-worker-2
任务156开始执行,当前线程名为ForkJoinPool-1-worker-4
任务151执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务158开始执行,当前线程名为ForkJoinPool-1-worker-6
任务152执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务159开始执行,当前线程名为ForkJoinPool-1-worker-5
任务150执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务160开始执行,当前线程名为ForkJoinPool-1-worker-3
任务157执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务161开始执行,当前线程名为ForkJoinPool-1-worker-2
任务158执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务162开始执行,当前线程名为ForkJoinPool-1-worker-6
任务155执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务153执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务163开始执行,当前线程名为ForkJoinPool-1-worker-1
任务164开始执行,当前线程名为ForkJoinPool-1-worker-7
任务156执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务165开始执行,当前线程名为ForkJoinPool-1-worker-4
任务154执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务166开始执行,当前线程名为ForkJoinPool-1-worker-0
任务159执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务167开始执行,当前线程名为ForkJoinPool-1-worker-5
任务160执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务168开始执行,当前线程名为ForkJoinPool-1-worker-3
任务161执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务169开始执行,当前线程名为ForkJoinPool-1-worker-2
任务164执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务163执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务170开始执行,当前线程名为ForkJoinPool-1-worker-7
任务171开始执行,当前线程名为ForkJoinPool-1-worker-1
任务165执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务166执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务162执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务173开始执行,当前线程名为ForkJoinPool-1-worker-0
任务172开始执行,当前线程名为ForkJoinPool-1-worker-4
任务174开始执行,当前线程名为ForkJoinPool-1-worker-6
任务167执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务175开始执行,当前线程名为ForkJoinPool-1-worker-5
任务168执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务176开始执行,当前线程名为ForkJoinPool-1-worker-3
任务171执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务174执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务177开始执行,当前线程名为ForkJoinPool-1-worker-1
任务178开始执行,当前线程名为ForkJoinPool-1-worker-6
任务169执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务173执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务179开始执行,当前线程名为ForkJoinPool-1-worker-2
任务180开始执行,当前线程名为ForkJoinPool-1-worker-0
任务170执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务181开始执行,当前线程名为ForkJoinPool-1-worker-7
任务172执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务182开始执行,当前线程名为ForkJoinPool-1-worker-4
任务175执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务183开始执行,当前线程名为ForkJoinPool-1-worker-5
任务176执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务184开始执行,当前线程名为ForkJoinPool-1-worker-3
任务181执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务185开始执行,当前线程名为ForkJoinPool-1-worker-7
任务177执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务180执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务186开始执行,当前线程名为ForkJoinPool-1-worker-1
任务187开始执行,当前线程名为ForkJoinPool-1-worker-0
任务178执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务179执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务189开始执行,当前线程名为ForkJoinPool-1-worker-2
任务188开始执行,当前线程名为ForkJoinPool-1-worker-6
任务182执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务190开始执行,当前线程名为ForkJoinPool-1-worker-4
任务183执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务184执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务191开始执行,当前线程名为ForkJoinPool-1-worker-5
任务192开始执行,当前线程名为ForkJoinPool-1-worker-3
任务185执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务193开始执行,当前线程名为ForkJoinPool-1-worker-7
任务186执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务187执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务188执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务194开始执行,当前线程名为ForkJoinPool-1-worker-1
任务189执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务197开始执行,当前线程名为ForkJoinPool-1-worker-2
任务195开始执行,当前线程名为ForkJoinPool-1-worker-0
任务190执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务198开始执行,当前线程名为ForkJoinPool-1-worker-4
任务196开始执行,当前线程名为ForkJoinPool-1-worker-6
任务192执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务199开始执行,当前线程名为ForkJoinPool-1-worker-3
任务191执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务200开始执行,当前线程名为ForkJoinPool-1-worker-5
任务194执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务197执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务202开始执行,当前线程名为ForkJoinPool-1-worker-2
任务201开始执行,当前线程名为ForkJoinPool-1-worker-1
任务193执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务203开始执行,当前线程名为ForkJoinPool-1-worker-7
任务198执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务195执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务205开始执行,当前线程名为ForkJoinPool-1-worker-0
任务204开始执行,当前线程名为ForkJoinPool-1-worker-4
任务196执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务206开始执行,当前线程名为ForkJoinPool-1-worker-6
任务199执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务207开始执行,当前线程名为ForkJoinPool-1-worker-3
任务200执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务208开始执行,当前线程名为ForkJoinPool-1-worker-5
任务203执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务209开始执行,当前线程名为ForkJoinPool-1-worker-7
任务202执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务210开始执行,当前线程名为ForkJoinPool-1-worker-2
任务201执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务211开始执行,当前线程名为ForkJoinPool-1-worker-1
任务205执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务212开始执行,当前线程名为ForkJoinPool-1-worker-0
任务206执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务213开始执行,当前线程名为ForkJoinPool-1-worker-6
任务204执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务214开始执行,当前线程名为ForkJoinPool-1-worker-4
任务207执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务215开始执行,当前线程名为ForkJoinPool-1-worker-3
任务208执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务216开始执行,当前线程名为ForkJoinPool-1-worker-5
任务209执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务217开始执行,当前线程名为ForkJoinPool-1-worker-7
任务213执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务212执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务219开始执行,当前线程名为ForkJoinPool-1-worker-0
任务211执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务210执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务221开始执行,当前线程名为ForkJoinPool-1-worker-2
任务220开始执行,当前线程名为ForkJoinPool-1-worker-1
任务218开始执行,当前线程名为ForkJoinPool-1-worker-6
任务214执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务222开始执行,当前线程名为ForkJoinPool-1-worker-4
任务215执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务223开始执行,当前线程名为ForkJoinPool-1-worker-3
任务216执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务224开始执行,当前线程名为ForkJoinPool-1-worker-5
任务217执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务225开始执行,当前线程名为ForkJoinPool-1-worker-7
任务221执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务218执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务226开始执行,当前线程名为ForkJoinPool-1-worker-2
任务219执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务227开始执行,当前线程名为ForkJoinPool-1-worker-6
任务228开始执行,当前线程名为ForkJoinPool-1-worker-0
任务220执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务229开始执行,当前线程名为ForkJoinPool-1-worker-1
任务222执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务224执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务230开始执行,当前线程名为ForkJoinPool-1-worker-4
任务231开始执行,当前线程名为ForkJoinPool-1-worker-5
任务223执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务232开始执行,当前线程名为ForkJoinPool-1-worker-3
任务225执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务233开始执行,当前线程名为ForkJoinPool-1-worker-7
任务226执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务227执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务234开始执行,当前线程名为ForkJoinPool-1-worker-2
任务228执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务236开始执行,当前线程名为ForkJoinPool-1-worker-0
任务235开始执行,当前线程名为ForkJoinPool-1-worker-6
任务229执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务237开始执行,当前线程名为ForkJoinPool-1-worker-1
任务230执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务238开始执行,当前线程名为ForkJoinPool-1-worker-4
任务231执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务239开始执行,当前线程名为ForkJoinPool-1-worker-5
任务232执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务240开始执行,当前线程名为ForkJoinPool-1-worker-3
任务236执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务237执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务233执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务242开始执行,当前线程名为ForkJoinPool-1-worker-1
任务243开始执行,当前线程名为ForkJoinPool-1-worker-7
任务241开始执行,当前线程名为ForkJoinPool-1-worker-0
任务234执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务235执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务244开始执行,当前线程名为ForkJoinPool-1-worker-2
任务245开始执行,当前线程名为ForkJoinPool-1-worker-6
任务240执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务238执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务246开始执行,当前线程名为ForkJoinPool-1-worker-4
任务239执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务247开始执行,当前线程名为ForkJoinPool-1-worker-3
任务248开始执行,当前线程名为ForkJoinPool-1-worker-5
任务243执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务249开始执行,当前线程名为ForkJoinPool-1-worker-7
任务244执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务242执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务250开始执行,当前线程名为ForkJoinPool-1-worker-2
任务251开始执行,当前线程名为ForkJoinPool-1-worker-1
任务245执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务241执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务252开始执行,当前线程名为ForkJoinPool-1-worker-6
任务253开始执行,当前线程名为ForkJoinPool-1-worker-0
任务246执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务248执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务254开始执行,当前线程名为ForkJoinPool-1-worker-4
任务255开始执行,当前线程名为ForkJoinPool-1-worker-5
任务247执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务256开始执行,当前线程名为ForkJoinPool-1-worker-3
任务249执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务250执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务252执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务254执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务251执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务253执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务261开始执行,当前线程名为ForkJoinPool-1-worker-6
任务262开始执行,当前线程名为ForkJoinPool-1-worker-1
任务257开始执行,当前线程名为ForkJoinPool-1-worker-7
任务259开始执行,当前线程名为ForkJoinPool-1-worker-0
任务260开始执行,当前线程名为ForkJoinPool-1-worker-4
任务258开始执行,当前线程名为ForkJoinPool-1-worker-2
任务255执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务263开始执行,当前线程名为ForkJoinPool-1-worker-5
任务256执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务264开始执行,当前线程名为ForkJoinPool-1-worker-3
任务262执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务260执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务261执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务258执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务257执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务259执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务263执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务264执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务265开始执行,当前线程名为ForkJoinPool-1-worker-3
任务266开始执行,当前线程名为ForkJoinPool-1-worker-6
任务267开始执行,当前线程名为ForkJoinPool-1-worker-5
任务268开始执行,当前线程名为ForkJoinPool-1-worker-1
任务269开始执行,当前线程名为ForkJoinPool-1-worker-4
任务270开始执行,当前线程名为ForkJoinPool-1-worker-2
任务271开始执行,当前线程名为ForkJoinPool-1-worker-0
任务272开始执行,当前线程名为ForkJoinPool-1-worker-7
任务267执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务270执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务272执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务271执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务266执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务269执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务265执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务273开始执行,当前线程名为ForkJoinPool-1-worker-5
任务268执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务274开始执行,当前线程名为ForkJoinPool-1-worker-1
任务275开始执行,当前线程名为ForkJoinPool-1-worker-2
任务276开始执行,当前线程名为ForkJoinPool-1-worker-7
任务277开始执行,当前线程名为ForkJoinPool-1-worker-3
任务278开始执行,当前线程名为ForkJoinPool-1-worker-6
任务279开始执行,当前线程名为ForkJoinPool-1-worker-4
任务280开始执行,当前线程名为ForkJoinPool-1-worker-0
任务273执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务279执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务282开始执行,当前线程名为ForkJoinPool-1-worker-4
任务278执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务283开始执行,当前线程名为ForkJoinPool-1-worker-6
任务277执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务284开始执行,当前线程名为ForkJoinPool-1-worker-3
任务276执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务285开始执行,当前线程名为ForkJoinPool-1-worker-7
任务275执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务286开始执行,当前线程名为ForkJoinPool-1-worker-2
任务281开始执行,当前线程名为ForkJoinPool-1-worker-5
任务274执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务287开始执行,当前线程名为ForkJoinPool-1-worker-1
任务280执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务288开始执行,当前线程名为ForkJoinPool-1-worker-0
任务283执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务285执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务289开始执行,当前线程名为ForkJoinPool-1-worker-6
任务281执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务291开始执行,当前线程名为ForkJoinPool-1-worker-5
任务290开始执行,当前线程名为ForkJoinPool-1-worker-7
任务284执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务286执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务293开始执行,当前线程名为ForkJoinPool-1-worker-2
任务282执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务294开始执行,当前线程名为ForkJoinPool-1-worker-4
任务288执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务295开始执行,当前线程名为ForkJoinPool-1-worker-0
任务287执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务296开始执行,当前线程名为ForkJoinPool-1-worker-1
任务292开始执行,当前线程名为ForkJoinPool-1-worker-3
任务291执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务290执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务289执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务298开始执行,当前线程名为ForkJoinPool-1-worker-7
任务297开始执行,当前线程名为ForkJoinPool-1-worker-5
任务299开始执行,当前线程名为ForkJoinPool-1-worker-6
任务294执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务296执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务301开始执行,当前线程名为ForkJoinPool-1-worker-1
任务295执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务300开始执行,当前线程名为ForkJoinPool-1-worker-4
任务302开始执行,当前线程名为ForkJoinPool-1-worker-0
任务292执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务293执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务304开始执行,当前线程名为ForkJoinPool-1-worker-2
任务303开始执行,当前线程名为ForkJoinPool-1-worker-3
任务297执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务305开始执行,当前线程名为ForkJoinPool-1-worker-5
任务298执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务306开始执行,当前线程名为ForkJoinPool-1-worker-7
任务300执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务307开始执行,当前线程名为ForkJoinPool-1-worker-4
任务299执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务308开始执行,当前线程名为ForkJoinPool-1-worker-6
任务303执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务309开始执行,当前线程名为ForkJoinPool-1-worker-3
任务301执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务310开始执行,当前线程名为ForkJoinPool-1-worker-1
任务302执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务304执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务312开始执行,当前线程名为ForkJoinPool-1-worker-2
任务311开始执行,当前线程名为ForkJoinPool-1-worker-0
任务305执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务313开始执行,当前线程名为ForkJoinPool-1-worker-5
任务308执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务309执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务315开始执行,当前线程名为ForkJoinPool-1-worker-3
任务307执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务316开始执行,当前线程名为ForkJoinPool-1-worker-4
任务310执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务312执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务318开始执行,当前线程名为ForkJoinPool-1-worker-2
任务314开始执行,当前线程名为ForkJoinPool-1-worker-6
任务317开始执行,当前线程名为ForkJoinPool-1-worker-1
任务311执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务319开始执行,当前线程名为ForkJoinPool-1-worker-0
任务306执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务320开始执行,当前线程名为ForkJoinPool-1-worker-7
任务313执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务321开始执行,当前线程名为ForkJoinPool-1-worker-5
任务319执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务317执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务322开始执行,当前线程名为ForkJoinPool-1-worker-1
任务323开始执行,当前线程名为ForkJoinPool-1-worker-0
任务314执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务324开始执行,当前线程名为ForkJoinPool-1-worker-6
任务318执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务325开始执行,当前线程名为ForkJoinPool-1-worker-2
任务320执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务326开始执行,当前线程名为ForkJoinPool-1-worker-7
任务315执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务316执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务327开始执行,当前线程名为ForkJoinPool-1-worker-3
任务328开始执行,当前线程名为ForkJoinPool-1-worker-4
任务321执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务329开始执行,当前线程名为ForkJoinPool-1-worker-5
任务324执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务323执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务328执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务327执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务332开始执行,当前线程名为ForkJoinPool-1-worker-3
任务333开始执行,当前线程名为ForkJoinPool-1-worker-4
任务322执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务334开始执行,当前线程名为ForkJoinPool-1-worker-1
任务330开始执行,当前线程名为ForkJoinPool-1-worker-6
任务331开始执行,当前线程名为ForkJoinPool-1-worker-0
任务325执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务335开始执行,当前线程名为ForkJoinPool-1-worker-2
任务326执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务336开始执行,当前线程名为ForkJoinPool-1-worker-7
任务329执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务337开始执行,当前线程名为ForkJoinPool-1-worker-5
任务332执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务338开始执行,当前线程名为ForkJoinPool-1-worker-3
任务335执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务339开始执行,当前线程名为ForkJoinPool-1-worker-2
任务333执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务340开始执行,当前线程名为ForkJoinPool-1-worker-4
任务334执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务341开始执行,当前线程名为ForkJoinPool-1-worker-1
任务330执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务342开始执行,当前线程名为ForkJoinPool-1-worker-6
任务331执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务343开始执行,当前线程名为ForkJoinPool-1-worker-0
任务336执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务344开始执行,当前线程名为ForkJoinPool-1-worker-7
任务337执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务345开始执行,当前线程名为ForkJoinPool-1-worker-5
任务339执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务346开始执行,当前线程名为ForkJoinPool-1-worker-2
任务338执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务347开始执行,当前线程名为ForkJoinPool-1-worker-3
任务340执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务348开始执行,当前线程名为ForkJoinPool-1-worker-4
任务341执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务342执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务349开始执行,当前线程名为ForkJoinPool-1-worker-1
任务350开始执行,当前线程名为ForkJoinPool-1-worker-6
任务343执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务351开始执行,当前线程名为ForkJoinPool-1-worker-0
任务344执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务352开始执行,当前线程名为ForkJoinPool-1-worker-7
任务345执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务353开始执行,当前线程名为ForkJoinPool-1-worker-5
任务349执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务354开始执行,当前线程名为ForkJoinPool-1-worker-1
任务346执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务355开始执行,当前线程名为ForkJoinPool-1-worker-2
任务347执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务356开始执行,当前线程名为ForkJoinPool-1-worker-3
任务351执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务357开始执行,当前线程名为ForkJoinPool-1-worker-0
任务348执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务358开始执行,当前线程名为ForkJoinPool-1-worker-4
任务350执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务359开始执行,当前线程名为ForkJoinPool-1-worker-6
任务352执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务360开始执行,当前线程名为ForkJoinPool-1-worker-7
任务353执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务361开始执行,当前线程名为ForkJoinPool-1-worker-5
任务354执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务355执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务362开始执行,当前线程名为ForkJoinPool-1-worker-1
任务363开始执行,当前线程名为ForkJoinPool-1-worker-2
任务357执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务364开始执行,当前线程名为ForkJoinPool-1-worker-0
任务356执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务359执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务366开始执行,当前线程名为ForkJoinPool-1-worker-6
任务365开始执行,当前线程名为ForkJoinPool-1-worker-3
任务358执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务367开始执行,当前线程名为ForkJoinPool-1-worker-4
任务360执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务368开始执行,当前线程名为ForkJoinPool-1-worker-7
任务361执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务369开始执行,当前线程名为ForkJoinPool-1-worker-5
任务364执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务366执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务370开始执行,当前线程名为ForkJoinPool-1-worker-6
任务371开始执行,当前线程名为ForkJoinPool-1-worker-0
任务362执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务372开始执行,当前线程名为ForkJoinPool-1-worker-1
任务363执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务373开始执行,当前线程名为ForkJoinPool-1-worker-2
任务365执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务374开始执行,当前线程名为ForkJoinPool-1-worker-3
任务367执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务375开始执行,当前线程名为ForkJoinPool-1-worker-4
任务368执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务376开始执行,当前线程名为ForkJoinPool-1-worker-7
任务369执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务377开始执行,当前线程名为ForkJoinPool-1-worker-5
任务371执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务370执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务378开始执行,当前线程名为ForkJoinPool-1-worker-0
任务379开始执行,当前线程名为ForkJoinPool-1-worker-6
任务372执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务373执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务380开始执行,当前线程名为ForkJoinPool-1-worker-1
任务381开始执行,当前线程名为ForkJoinPool-1-worker-2
任务374执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务382开始执行,当前线程名为ForkJoinPool-1-worker-3
任务375执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务383开始执行,当前线程名为ForkJoinPool-1-worker-4
任务376执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务384开始执行,当前线程名为ForkJoinPool-1-worker-7
任务377执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务385开始执行,当前线程名为ForkJoinPool-1-worker-5
任务381执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务378执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务386开始执行,当前线程名为ForkJoinPool-1-worker-2
任务383执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务379执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务380执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务389开始执行,当前线程名为ForkJoinPool-1-worker-1
任务382执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务390开始执行,当前线程名为ForkJoinPool-1-worker-3
任务388开始执行,当前线程名为ForkJoinPool-1-worker-4
任务387开始执行,当前线程名为ForkJoinPool-1-worker-0
任务391开始执行,当前线程名为ForkJoinPool-1-worker-6
任务384执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务392开始执行,当前线程名为ForkJoinPool-1-worker-7
任务385执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务393开始执行,当前线程名为ForkJoinPool-1-worker-5
任务389执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务388执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务387执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务390执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务391执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务398开始执行,当前线程名为ForkJoinPool-1-worker-6
任务397开始执行,当前线程名为ForkJoinPool-1-worker-1
任务396开始执行,当前线程名为ForkJoinPool-1-worker-0
任务394开始执行,当前线程名为ForkJoinPool-1-worker-4
任务395开始执行,当前线程名为ForkJoinPool-1-worker-3
任务386执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务399开始执行,当前线程名为ForkJoinPool-1-worker-2
任务392执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务400开始执行,当前线程名为ForkJoinPool-1-worker-7
任务393执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务401开始执行,当前线程名为ForkJoinPool-1-worker-5
任务397执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务399执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务402开始执行,当前线程名为ForkJoinPool-1-worker-1
任务395执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务404开始执行,当前线程名为ForkJoinPool-1-worker-3
任务394执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务405开始执行,当前线程名为ForkJoinPool-1-worker-4
任务398执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务406开始执行,当前线程名为ForkJoinPool-1-worker-6
任务396执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务407开始执行,当前线程名为ForkJoinPool-1-worker-0
任务403开始执行,当前线程名为ForkJoinPool-1-worker-2
任务400执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务408开始执行,当前线程名为ForkJoinPool-1-worker-7
任务401执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务409开始执行,当前线程名为ForkJoinPool-1-worker-5
任务403执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务410开始执行,当前线程名为ForkJoinPool-1-worker-2
任务402执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务405执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务404执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务413开始执行,当前线程名为ForkJoinPool-1-worker-3
任务411开始执行,当前线程名为ForkJoinPool-1-worker-1
任务406执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务414开始执行,当前线程名为ForkJoinPool-1-worker-6
任务412开始执行,当前线程名为ForkJoinPool-1-worker-4
任务407执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务415开始执行,当前线程名为ForkJoinPool-1-worker-0
任务408执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务416开始执行,当前线程名为ForkJoinPool-1-worker-7
任务409执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务417开始执行,当前线程名为ForkJoinPool-1-worker-5
任务410执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务418开始执行,当前线程名为ForkJoinPool-1-worker-2
任务413执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务419开始执行,当前线程名为ForkJoinPool-1-worker-3
任务415执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务420开始执行,当前线程名为ForkJoinPool-1-worker-0
任务412执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务421开始执行,当前线程名为ForkJoinPool-1-worker-4
任务414执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务422开始执行,当前线程名为ForkJoinPool-1-worker-6
任务411执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务423开始执行,当前线程名为ForkJoinPool-1-worker-1
任务416执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务424开始执行,当前线程名为ForkJoinPool-1-worker-7
任务417执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务425开始执行,当前线程名为ForkJoinPool-1-worker-5
任务422执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务426开始执行,当前线程名为ForkJoinPool-1-worker-6
任务419执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务420执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务421执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务429开始执行,当前线程名为ForkJoinPool-1-worker-4
任务427开始执行,当前线程名为ForkJoinPool-1-worker-3
任务418执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务430开始执行,当前线程名为ForkJoinPool-1-worker-2
任务428开始执行,当前线程名为ForkJoinPool-1-worker-0
任务423执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务431开始执行,当前线程名为ForkJoinPool-1-worker-1
任务424执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务432开始执行,当前线程名为ForkJoinPool-1-worker-7
任务425执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务433开始执行,当前线程名为ForkJoinPool-1-worker-5
任务426执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务434开始执行,当前线程名为ForkJoinPool-1-worker-6
任务427执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务435开始执行,当前线程名为ForkJoinPool-1-worker-3
任务430执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务436开始执行,当前线程名为ForkJoinPool-1-worker-2
任务428执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务437开始执行,当前线程名为ForkJoinPool-1-worker-0
任务429执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务438开始执行,当前线程名为ForkJoinPool-1-worker-4
任务431执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务439开始执行,当前线程名为ForkJoinPool-1-worker-1
任务432执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务440开始执行,当前线程名为ForkJoinPool-1-worker-7
任务433执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务441开始执行,当前线程名为ForkJoinPool-1-worker-5
任务434执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务442开始执行,当前线程名为ForkJoinPool-1-worker-6
任务437执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务443开始执行,当前线程名为ForkJoinPool-1-worker-0
任务435执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务436执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务445开始执行,当前线程名为ForkJoinPool-1-worker-2
任务444开始执行,当前线程名为ForkJoinPool-1-worker-3
任务439执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务446开始执行,当前线程名为ForkJoinPool-1-worker-1
任务438执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务447开始执行,当前线程名为ForkJoinPool-1-worker-4
任务440执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务448开始执行,当前线程名为ForkJoinPool-1-worker-7
任务441执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务449开始执行,当前线程名为ForkJoinPool-1-worker-5
任务442执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务450开始执行,当前线程名为ForkJoinPool-1-worker-6
任务443执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务451开始执行,当前线程名为ForkJoinPool-1-worker-0
任务444执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务452开始执行,当前线程名为ForkJoinPool-1-worker-3
任务446执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务445执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务454开始执行,当前线程名为ForkJoinPool-1-worker-2
任务453开始执行,当前线程名为ForkJoinPool-1-worker-1
任务447执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务455开始执行,当前线程名为ForkJoinPool-1-worker-4
任务448执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务456开始执行,当前线程名为ForkJoinPool-1-worker-7
任务449执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务457开始执行,当前线程名为ForkJoinPool-1-worker-5
任务450执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务458开始执行,当前线程名为ForkJoinPool-1-worker-6
任务451执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务452执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务459开始执行,当前线程名为ForkJoinPool-1-worker-0
任务460开始执行,当前线程名为ForkJoinPool-1-worker-3
任务453执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务461开始执行,当前线程名为ForkJoinPool-1-worker-1
任务455执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务462开始执行,当前线程名为ForkJoinPool-1-worker-4
任务454执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务463开始执行,当前线程名为ForkJoinPool-1-worker-2
任务456执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务464开始执行,当前线程名为ForkJoinPool-1-worker-7
任务457执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务465开始执行,当前线程名为ForkJoinPool-1-worker-5
任务458执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务466开始执行,当前线程名为ForkJoinPool-1-worker-6
任务460执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务467开始执行,当前线程名为ForkJoinPool-1-worker-3
任务459执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务468开始执行,当前线程名为ForkJoinPool-1-worker-0
任务463执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务469开始执行,当前线程名为ForkJoinPool-1-worker-2
任务461执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务470开始执行,当前线程名为ForkJoinPool-1-worker-1
任务462执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务471开始执行,当前线程名为ForkJoinPool-1-worker-4
任务464执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务472开始执行,当前线程名为ForkJoinPool-1-worker-7
任务465执行完毕,当前线程名为ForkJoinPool-1-worker-5
任务473开始执行,当前线程名为ForkJoinPool-1-worker-5
任务466执行完毕,当前线程名为ForkJoinPool-1-worker-6
任务474开始执行,当前线程名为ForkJoinPool-1-worker-6
任务467执行完毕,当前线程名为ForkJoinPool-1-worker-3
任务475开始执行,当前线程名为ForkJoinPool-1-worker-3
任务468执行完毕,当前线程名为ForkJoinPool-1-worker-0
任务476开始执行,当前线程名为ForkJoinPool-1-worker-0
任务469执行完毕,当前线程名为ForkJoinPool-1-worker-2
任务471执行完毕,当前线程名为ForkJoinPool-1-worker-4
任务478开始执行,当前线程名为ForkJoinPool-1-worker-4
任务470执行完毕,当前线程名为ForkJoinPool-1-worker-1
任务479开始执行,当前线程名为ForkJoinPool-1-worker-1
任务477开始执行,当前线程名为ForkJoinPool-1-worker-2
任务472执行完毕,当前线程名为ForkJoinPool-1-worker-7
任务480开始执行,当前线程名为ForkJoinPool-1-worker-7

Process finished with exit code 0

注意这里同等配置,在苹果M1没压力,在windows CPU 8核的CPU飙高100%~

为什么要用线程池而不用Thread?

这个问题对于老手来说是废话,对于新手来说就要注意了。首先我不否认说直接用Thread不好,一切还是要看你的场景,如果你的整个系统只有一或几处thread,并且执行都是很短时间及次数很少,当然我不否认这样也是没有问题,但是如果你有以下的情况就要注意了。

1.执行次数非常频繁;

2.执行的地点非常多;

3.执行的线程时间长度不可预知或很长;

那么可能出现如下的情况:

1.CPU或内存忽高忽地,大半夜默名奇妙有告警;

2.经常不知道为什么FullGc;

3.代码耦合不敢乱改;

4.出现很多不可控因素,比如内存一直被占着,线程数量太高,系统卡顿 当然还有很多~

...

所以说线程池  统一管控(分配、调优、监控)资源 一定程度保障系统的稳定性,几大点如下:

  1. 资源控制:线程池可以限制同时运行的线程数量,防止过度消耗系统资源和导致系统崩溃。

  2. 提高效率:线程池可以重复利用已创建的线程,避免了频繁创建和销毁线程的开销,提高了程序的执行效率。

  3. 提高响应速度:线程池可以预先创建并初始化一定数量的线程,当任务到来时,可以立即执行,提高了程序的响应速度。

  4. 简化编程:使用线程池可以让程序员专注于业务逻辑的实现,而不必关心线程的创建和管理,简化了编程过程。使用线程池可以更好地控制系统资源、提高程序的效率和响应速度,并且简化编程过程。因此,在多线程编程中,使用线程池是一种更加优秀的选择。

源码学习

Executor框架

Executor框架是Java中用于管理线程池的框架,它提供了一种将任务提交和执行分离的机制,使得线程的创建和销毁可以由框架自动管理,从而减少了线程创建和上下文切换的开销,提高了系统的性能。Executor框架主要包含以下三个核心组件:

  1. Executor 接口:该接口定义了一个execute方法,用于将任务提交给线程池执行。

  2. ExecutorService 接口:该接口继承了Executor接口,并增加了一些管理线程池的方法,例如submit方法、shutdown方法等。

  3. ThreadPoolExecutor 类:该类是线程池的实现类,它提供了丰富的参数配置,可以根据不同的需求创建不同的线程池。例如,可以设置核心线程数、最大线程数、队列容量、拒绝策略等参数。使用Executor框架可以方便地实现线程池的创建和管理,提高系统的性能和稳定性。同时,Executor框架还提供了一些方便的工具类,例如Executors类、ScheduledExecutorService接口等,可以实现定时任务、延时任务、周期性任务等功能,非常适合于多线程编程和并发处理。

92b951a87cf67f9313e87c9e5f7795b2.png

java.util.concurrent.Executor

//该接口定义了线程池的基本执行方法
public interface Executor {

    //在将来的某个时间执行给定的命令。该命令可以在新线程、池线程或调用线程中执行,由Executor实现自行决定。Params: command -可运行任务抛出:RejectedExecutionException -如果该任务不能被接受执行NullPointerException -如果命令为空
    void execute(Runnable command);
}

java.util.concurrent.ExecutorService

/**
 * @author: csh
 * @Date: 2023/3/7 23:08
 * @Description:
 */
public interface ExecutorServiceStudy {

    /**
     * shutdown方法用于关闭线程池,不会立即停止所有任务的执行,而是等待所有任务执行完毕后再关闭。
     */
    void shutdown();

    /**
     * shutdownNow方法用于关闭线程池,并尝试停止所有正在执行的任务。
     */
    List<Runnable> shutdownNow();

    /**
     * isShutdown方法用于判断线程池是否已经关闭。
     */
    boolean isShutdown();

    /**
     * isTerminated方法用于判断线程池是否已经关闭,并且所有任务都已经执行完毕。
     */
    boolean isTerminated();

    /**
     * awaitTermination方法用于等待线程池关闭,并且所有任务都已经执行完毕。
     */
    boolean awaitTermination(long timeout, TimeUnit unit)
            throws InterruptedException;

    /**
     * submit方法用于提交一个Callable或Runnable任务到线程池,并返回一个Future对象,可以通过Future对象获取任务的执行结果或取消任务的执行。
     */
    <T> Future<T> submit(Callable<T> task);

    /**
     * Submits提交一个可运行任务以供执行,并返回表示该任务的Future。Future的get方法将在成功完成时返回给定的结果。
     */
    <T> Future<T> submit(Runnable task, T result);

    /**
     * 提交一个可运行任务以供执行,并返回表示该任务的Future。Future的get方法将在成功完成时返回null。
     */
    Future<?> submit(Runnable task);

    /**
     * 执行给定的任务,在所有任务完成时返回包含它们的状态和结果的Futures列表。的未来。对于返回列表的每个元素,isDone都是true。
     */
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
            throws InterruptedException;

    /**
     * 带超时时间 同上类似
     */
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                  long timeout, TimeUnit unit)
            throws InterruptedException;

    /**
     * 执行给定的任务,如果有成功完成的任务,则返回成功完成的任务的结果(即,没有抛出异常)。在正常或异常返回时,未完成的任务将被取消。如果在执行此操作时修改了给定的集合,则此方法的结果是未定义的。
     */
    <T> T invokeAny(Collection<? extends Callable<T>> tasks)
            throws InterruptedException, ExecutionException;

    /**
     * 同上类似 带超时时间
     */
    <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                    long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException;
}

java.util.concurrent.AbstractExecutorService

package java.util.concurrent;
import java.util.*;
//提供ExecutorService执行方法的默认实现。该类是一个抽象类仅供继承
public abstract class AbstractExecutorService implements ExecutorService {

    //为给定的可运行对象和默认值返回一个RunnableFuture。
    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        return new FutureTask<T>(runnable, value);
    }

    //同上
    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }

    //任务提交
    public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        //创建RunnableFuture
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        //执行
        execute(ftask);
        //返回
        return ftask;
    }

    //任务提交
    //task为任务
    //result 为自定义返回结果
    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task, result);
        execute(ftask);
        return ftask;
    }

    //任务提交的方法
    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }

    /**
     * 该方法是实现唤醒任意一个方法
     */
    private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
                              boolean timed, long nanos)
        throws InterruptedException, ExecutionException, TimeoutException {
        if (tasks == null)
            throw new NullPointerException();
            //获取长度
        int ntasks = tasks.size();
        //为0抛出异常
        if (ntasks == 0)
            throw new IllegalArgumentException();
        //创建阶列
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
        //这里一个
        ExecutorCompletionService<T> ecs =
            new ExecutorCompletionService<T>(this);

        // For efficiency, especially in executors with limited
        // parallelism, check to see if previously submitted tasks are
        // done before submitting more of them. This interleaving
        // plus the exception mechanics account for messiness of main
        // loop.

        try {
            // Record exceptions so that if we fail to obtain any
            // result, we can throw the last exception we got.
            ExecutionException ee = null;
            final long deadline = timed ? System.nanoTime() + nanos : 0L;
            Iterator<? extends Callable<T>> it = tasks.iterator();

            // Start one task for sure; the rest incrementally
            //确定开始的任务
            futures.add(ecs.submit(it.next()));
            --ntasks;//递减
            int active = 1;
            //循环调用
            for (;;) {
                //获取队列的头,如果没有为null (阻塞队列)
                Future<T> f = ecs.poll();
                //为空
                if (f == null) {
                    //如果大于0
                    if (ntasks > 0) {
                        --ntasks;
                        //指向下一个节点
                        futures.add(ecs.submit(it.next()));
                        ++active;
                    }
                    //为0 最后一个了,跳出
                    else if (active == 0)
                        break;
                    //其他逻辑 传进来timed 为true 进行超时时间判断和计算
                    else if (timed) {
                        f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
                        if (f == null)
                            throw new TimeoutException();
                        nanos = deadline - System.nanoTime();
                    }
                    //所有都没有 检索并删除表示下一个已完成任务的Future,如果没有则等待。
                    else
                        f = ecs.take();
                }
                //如果不为空
                if (f != null) {
                    //自减 
                    --active;
                    try {
                        //返回 这里如果获取异常下面做了处理
                        return f.get();
                    } catch (ExecutionException eex) {
                        ee = eex;
                    } catch (RuntimeException rex) {
                        ee = new ExecutionException(rex);
                    }
                }
            }
            //如果异常类型为空 进行初始化
            if (ee == null)
                ee = new ExecutionException();
            //然后抛出
            throw ee;

        } finally {
            //最后做下 所有任务的取消
            for (int i = 0, size = futures.size(); i < size; i++)
                futures.get(i).cancel(true);
        }
    }
    //调用以上的方法
    public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException {
        try {
            return doInvokeAny(tasks, false, 0);
        } catch (TimeoutException cannotHappen) {
            assert false;
            return null;
        }
    }
    //带过期时间的调用任意一个任务
    public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                           long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
        return doInvokeAny(tasks, true, unit.toNanos(timeout));
    }
    //调用所有任务
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException {
        if (tasks == null)
            throw new NullPointerException();
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
        boolean done = false;
        try {
            for (Callable<T> t : tasks) {
                //注意这个RunnableFuture 是runnable和future的结合体,用于表示一个异步任务的结果
                RunnableFuture<T> f = newTaskFor(t);
                futures.add(f);
                //执行
                execute(f);
            }
            for (int i = 0, size = futures.size(); i < size; i++) {
                Future<T> f = futures.get(i);
                if (!f.isDone()) {
                    try {
                        f.get();
                    } catch (CancellationException ignore) {
                    } catch (ExecutionException ignore) {
                    }
                }
            }
            done = true;
            return futures;
        } finally {
            if (!done)
                for (int i = 0, size = futures.size(); i < size; i++)
                    futures.get(i).cancel(true);
        }
    }
    //带过期时间调用所有任务
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                         long timeout, TimeUnit unit)
        throws InterruptedException {
        if (tasks == null)
            throw new NullPointerException();
        long nanos = unit.toNanos(timeout);
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
        boolean done = false;
        try {
            for (Callable<T> t : tasks)
                futures.add(newTaskFor(t));

            final long deadline = System.nanoTime() + nanos;
            final int size = futures.size();

            // Interleave time checks and calls to execute in case
            // executor doesn't have any/much parallelism.
            for (int i = 0; i < size; i++) {
                execute((Runnable)futures.get(i));
                nanos = deadline - System.nanoTime();
                if (nanos <= 0L)
                    return futures;
            }

            for (int i = 0; i < size; i++) {
                Future<T> f = futures.get(i);
                if (!f.isDone()) {
                    if (nanos <= 0L)
                        return futures;
                    try {
                        f.get(nanos, TimeUnit.NANOSECONDS);
                    } catch (CancellationException ignore) {
                    } catch (ExecutionException ignore) {
                    } catch (TimeoutException toe) {
                        return futures;
                    }
                    nanos = deadline - System.nanoTime();
                }
            }
            done = true;
            return futures;
        } finally {
            if (!done)
                for (int i = 0, size = futures.size(); i < size; i++)
                    futures.get(i).cancel(true);
        }
    }

}

AbstractExecutorService中提供的方法实现包括以下几个方面:

  1. newTaskFor()方法:该方法用于创建一个RunnableFuture对象,它是Future和Runnable的结合体,可以用于表示一个异步任务的执行结果。在AbstractExecutorService中,该方法的默认实现是使用FutureTask类创建一个RunnableFuture对象,如果需要使用其它实现,可以在子类中重写该方法。

  2. submit()方法:该方法是ExecutorService接口中定义的方法,用于提交一个任务给线程池执行。在AbstractExecutorService中,提供了Runnable和Callable两种类型的任务提交方法,它们都是调用newTaskFor()方法创建一个RunnableFuture对象,并将其交给execute()方法执行。如果需要实现自定义的任务提交逻辑,可以在子类中重写该方法。需要注意的是,AbstractExecutorService是一个抽象类,不能直接使用,需要通过继承该类并实现其它方法来实现自定义的线程池。

java.util.concurrent.FutureTask

这个是一个核心类。

state状态说明:

  1. NEW:初始状态,表示FutureTask对象已经创建,但任务还没有开始执行。

  2. COMPLETING:表示任务已经执行完成,但还没有将结果设置到FutureTask中。

  3. NORMAL:表示任务执行成功,并且已经将结果设置到FutureTask中。

  4. EXCEPTIONAL:表示任务执行过程中抛出了异常,并且已经将异常信息设置到FutureTask中。

  5. CANCELLED:表示任务已经被取消。

  6. INTERRUPTING:表示任务正在被中断。

  7. INTERRUPTED:表示任务已经被中断。

package java.util.concurrent;
import java.util.concurrent.locks.LockSupport;
//一个可取消的异步计算。
//这里要注意一下,这个是实现了RunnableFuture 而RunnableFuture是 继承了:Runnable, Future<V>
public class FutureTask<V> implements RunnableFuture<V> {


    /**
     * The run state of this task, initially NEW. The run state
     * transitions to a terminal state only in methods set,
     * setException, and cancel. During completion, state may take on
     * transient values of COMPLETING (while outcome is being set) or
     * INTERRUPTING (only while interrupting the runner to satisfy a
     * cancel(true)). Transitions from these intermediate to final
     * states use cheaper ordered/lazy writes because values are unique
     * and cannot be further modified.
     *
     * Possible state transitions:
     * NEW -> COMPLETING -> NORMAL
     * NEW -> COMPLETING -> EXCEPTIONAL
     * NEW -> CANCELLED
     * NEW -> INTERRUPTING -> INTERRUPTED
     */
    //状态 可能的状态转换:NEW -> completion -> NORMAL NEW -> completion -> exception NEW -> CANCELLED NEW -> INTERRUPTED -> INTERRUPTED
    private volatile int state;
    //实始化状态
    private static final int NEW = 0;
    /**
NEW:初始状态,表示FutureTask对象已经创建,但任务还没有开始执行。
COMPLETING:表示任务已经执行完成,但还没有将结果设置到FutureTask中。
NORMAL:表示任务执行成功,并且已经将结果设置到FutureTask中。
EXCEPTIONAL:表示任务执行过程中抛出了异常,并且已经将异常信息设置到FutureTask中。
CANCELLED:表示任务已经被取消。
INTERRUPTING:表示任务正在被中断。
INTERRUPTED:表示任务已经被中断。
    **/
    private static final int COMPLETING = 1;
    private static final int NORMAL = 2;
    private static final int EXCEPTIONAL = 3;
    private static final int CANCELLED = 4;
    private static final int INTERRUPTING = 5;
    private static final int INTERRUPTED = 6;

    /** 调用的对象 ,运行后为空 */
    private Callable<V> callable;
    /**要返回的结果或跑出的异常 */
    private Object outcome; // non-volatile, protected by state reads/writes
    /** 运行可调用对象的线程;在run()期间进行case */
    private volatile Thread runner;
    /** 等待线程的Treiber堆栈 */
    private volatile WaitNode waiters;

    //返回已完成任务的结果或抛出异常。完成状态值
    @SuppressWarnings("unchecked")
    private V report(int s) throws ExecutionException {
        Object x = outcome;
        if (s == NORMAL)
            return (V)x;
        if (s >= CANCELLED)
            throw new CancellationException();
        throw new ExecutionException((Throwable)x);
    }

    //构造方法
    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW; // ensure visibility of callable
    }

   //构造方法
    public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
        this.state = NEW; // ensure visibility of callable
    }
    //判断是否取消
    public boolean isCancelled() {
        return state >= CANCELLED;
    }
    //判断是否已完成
    public boolean isDone() {
        return state != NEW;
    }
    //取消方法
    public boolean cancel(boolean mayInterruptIfRunning) {
        //状态不为初始 且
        if (!(state == NEW && cas锁获取成功 返回 false
              UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
                  mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
            return false;
        try { // in case call to interrupt throws exception
            if (mayInterruptIfRunning) {
                try {
                    Thread t = runner;
                    //不为空进行中断
                    if (t != null)
                        t.interrupt();
                } finally { // final state
                    //更新状态
                    UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
                }
            }
        } finally {
            //删除并通知所有等待线程,调用done(),并空出可调用对象。
            finishCompletion();
        }
        //返回成功
        return true;
    }

    //获取线程
    public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    }

    //带超时时间 获取
    public V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
        if (unit == null)
            throw new NullPointerException();
        int s = state;
        if (s <= COMPLETING &&
            (s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
            throw new TimeoutException();
        return report(s);
    }

    ///重写方法
    protected void done() { }

    //设置结果为指定值
    protected void set(V v) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
            outcome = v;
            UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
            finishCompletion();
        }
    }

    //设置结果 出异常
    protected void setException(Throwable t) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
            outcome = t;
            UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state
            finishCompletion();
        }
    }
    //运行方法
    public void run() {
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return;
        try {
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex);
                }
                if (ran)
                    set(result);
            }
        } finally {
            // runner must be non-null until state is settled to
            // prevent concurrent calls to run()
            runner = null;
            // state must be re-read after nulling runner to prevent
            // leaked interrupts
            int s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
    }

    //执行不进行设置结果
    protected boolean runAndReset() {
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return false;
        boolean ran = false;
        int s = state;
        try {
            Callable<V> c = callable;
            if (c != null && s == NEW) {
                try {
                    c.call(); // don't set result
                    ran = true;
                } catch (Throwable ex) {
                    setException(ex);
                }
            }
        } finally {
            // runner must be non-null until state is settled to
            // prevent concurrent calls to run()
            runner = null;
            // state must be re-read after nulling runner to prevent
            // leaked interrupts
            s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
        return ran && s == NEW;
    }

    //确保任何来自可能的取消(true)的中断只在运行或runAndReset时传递给任务。
    private void handlePossibleCancellationInterrupt(int s) {
        // It is possible for our interrupter to stall before getting a
        // chance to interrupt us. Let's spin-wait patiently.
        if (s == INTERRUPTING)
            while (state == INTERRUPTING)
                Thread.yield(); // wait out pending interrupt

        // assert state == INTERRUPTED;

        // We want to clear any interrupt we may have received from
        // cancel(true). However, it is permissible to use interrupts
        // as an independent mechanism for a task to communicate with
        // its caller, and there is no way to clear only the
        // cancellation interrupt.
        //
        // Thread.interrupted();
    }

    //在Treiber堆栈中记录等待线程的简单链表节点。
    static final class WaitNode {
        volatile Thread thread;
        volatile WaitNode next;
        WaitNode() { thread = Thread.currentThread(); }
    }

   //删除并通知所有等待线程,调用done(),并空出可调用对象。
    private void finishCompletion() {
        // assert state > COMPLETING;
        for (WaitNode q; (q = waiters) != null;) {
            if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) {
                for (;;) {
                    Thread t = q.thread;
                    if (t != null) {
                        q.thread = null;
                        LockSupport.unpark(t);
                    }
                    WaitNode next = q.next;
                    if (next == null)
                        break;
                    q.next = null; // unlink to help gc
                    q = next;
                }
                break;
            }
        }

        done();

        callable = null; // to reduce footprint
    }

    //在中断或超时时等待完成或中止
    private int awaitDone(boolean timed, long nanos)
        throws InterruptedException {
        final long deadline = timed ? System.nanoTime() + nanos : 0L;
        WaitNode q = null;
        boolean queued = false;
        for (;;) {
            if (Thread.interrupted()) {
                removeWaiter(q);
                throw new InterruptedException();
            }

            int s = state;
            if (s > COMPLETING) {
                if (q != null)
                    q.thread = null;
                return s;
            }
            else if (s == COMPLETING) // cannot time out yet
                Thread.yield();
            else if (q == null)
                q = new WaitNode();
            else if (!queued)
                queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
                                                     q.next = waiters, q);
            else if (timed) {
                nanos = deadline - System.nanoTime();
                if (nanos <= 0L) {
                    removeWaiter(q);
                    return state;
                }
                LockSupport.parkNanos(this, nanos);
            }
            else
                LockSupport.park(this);
        }
    }

    //尝试断开超时或中断的等待节点的链接,以避免累积垃圾。
    private void removeWaiter(WaitNode node) {
        if (node != null) {
            node.thread = null;
            retry:
            for (;;) { // restart on removeWaiter race
                for (WaitNode pred = null, q = waiters, s; q != null; q = s) {
                    s = q.next;
                    if (q.thread != null)
                        pred = q;
                    else if (pred != null) {
                        pred.next = s;
                        if (pred.thread == null) // check for race
                            continue retry;
                    }
                    else if (!UNSAFE.compareAndSwapObject(this, waitersOffset,
                                                          q, s))
                        continue retry;
                }
                break;
            }
        }
    }
    //已下是初始化的信息
    // Unsafe mechanics
    private static final sun.misc.Unsafe UNSAFE;
    private static final long stateOffset;
    private static final long runnerOffset;
    private static final long waitersOffset;
    static {
        try {
            UNSAFE = sun.misc.Unsafe.getUnsafe();
            Class<?> k = FutureTask.class;
            stateOffset = UNSAFE.objectFieldOffset
                (k.getDeclaredField("state"));
            runnerOffset = UNSAFE.objectFieldOffset
                (k.getDeclaredField("runner"));
            waitersOffset = UNSAFE.objectFieldOffset
                (k.getDeclaredField("waiters"));
        } catch (Exception e) {
            throw new Error(e);
        }
    }

}

java.util.concurrent.ThreadPoolExecutor

这个就是主类的学习了,核心的线程池实现。

package java.util.concurrent;

import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.*;
//一种执行程序服务,它使用可能有多个池化线程之一执行每个提交的任务,通常使用执行程序工厂方法进行配置。
//线程池解决了两个不同的问题:由于减少了每个任务的调用开销,它们通常在执行大量异步任务时提供改进的性能,并且它们提供了一种绑定和管理执行任务集合时消耗的资源(包括线程)的方法。
public class ThreadPoolExecutor extends AbstractExecutorService {
    //主池控制状态 ctl,是一个原子整数,包含两个概念字段 workerCount,指示线程运行状态的有效数量,指示是否正在运行、关闭等 为了将它们打包到一个 int 中,我们将 workerCount 限制为 (2^29)-1(约 5 亿)线程,而不是 (2^31)-1(20 亿)否则可表示。
    /* 相关方法:
           runStateOf:获取运行状态;
           workerCountOf:获取活动线程数;
           ctlOf:获取运行状态和活动线程数的值。
    */
    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    private static final int COUNT_BITS = Integer.SIZE - 3;
    private static final int CAPACITY = (1 << COUNT_BITS) - 1;

    //以下是高位的状态
    //高3位为111 线程池正在运行,可以接受新的任务。以及对已添加的任务进行处理。
    private static final int RUNNING = -1 << COUNT_BITS;
    //高3位为000 线程池正在关闭,不再接受新的任务,但会继续处理已经提交的任务。
    private static final int SHUTDOWN = 0 << COUNT_BITS;
    //高3位为001 线程池已经停止,不再接受新的任务,也不会处理已经提交的任务,并且会中断正在执行的任务。
    private static final int STOP = 1 << COUNT_BITS;
    //高3位为010 所有的任务都已经终止,线程数量为 0,即将进入 TERMINATED 状态。
    private static final int TIDYING = 2 << COUNT_BITS;
    //高3位为011 线程池已经终止,不再接受新的任务。
    private static final int TERMINATED = 3 << COUNT_BITS;

    // Packing and unpacking ctl
    //获取运行状态
    private static int runStateOf(int c)     { return c & ~CAPACITY; }
    //获取活动线程数
    private static int workerCountOf(int c)  { return c & CAPACITY; }
    //获取运行状态和活动线程数的值
    private static int ctlOf(int rs, int wc) { return rs | wc; }

    //用于判断 c是否小于s 一般用于状态判断
    private static boolean runStateLessThan(int c, int s) {
        return c < s;
    }
    //用于判断 c大于等于s
    private static boolean runStateAtLeast(int c, int s) {
        return c >= s;
    }
    //判断是否正在运行
    private static boolean isRunning(int c) {
        return c < SHUTDOWN;
    }

    //cas方式进行状态递增
    private boolean compareAndIncrementWorkerCount(int expect) {
        return ctl.compareAndSet(expect, expect + 1);
    }

    //cas方式状态递减
    private boolean compareAndDecrementWorkerCount(int expect) {
        return ctl.compareAndSet(expect, expect - 1);
    }

    //用于线程突然中断调用
    private void decrementWorkerCount() {
        do {} while (! compareAndDecrementWorkerCount(ctl.get()));
    }

    //用于保存任务和移交给工作线程的队列。
    private final BlockingQueue<Runnable> workQueue;

    //重入锁
    private final ReentrantLock mainLock = new ReentrantLock();

    /**
     * 线程池的工作线程集
     */
    private final HashSet<Worker> workers = new HashSet<Worker>();

    /**
     * 等待终止的条件
     */
    private final Condition termination = mainLock.newCondition();

    /**
     * 线程池曾经达到的最大线程数量
     */
    private int largestPoolSize;

    /**
     * 已完成的任务数量
     */
    private long completedTaskCount;

    //线程工厂,用于创建新的线程。
    private volatile ThreadFactory threadFactory;

    /**
     * 任务拒绝处理器,当工作队列已满且当前线程数等于最大线程数时,按照提交的任务拒绝策略来处理任务
     */
    private volatile RejectedExecutionHandler handler;

    //线程空闲超时时间,当线程池中的线程数量大于核心线程数时,空闲线程保持活跃的时间。
    private volatile long keepAliveTime;

    /**
     * 如果为 false(默认值),则核心线程即使在空闲时也保持活动状态。如果为 true,则核心线程使用 keepAliveTime 来超时等待工作。
     */
    private volatile boolean allowCoreThreadTimeOut;

    /**
     * 线程池核心线程数量,即使线程处于空闲状态,也不会被回收。
     */
    private volatile int corePoolSize;

    /**
     * 线程池最大线程数量,当工作队列已满且当前线程数小于最大线程数时,会创建新的线程来处理任务。
     */
    private volatile int maximumPoolSize;

    /**
     * 默认的拒绝策略
     */
    private static final RejectedExecutionHandler defaultHandler =
        new AbortPolicy();

    /**
     * 关闭和关闭现在的调用方所需的权限。
     */
    private static final RuntimePermission shutdownPerm =
        new RuntimePermission("modifyThread");

    /*执行终结器时要使用的上下文 */
    private final AccessControlContext acc;

    /**
     * Class Worker 主要维护运行任务的线程的中断控制状态,以及其他次要簿记。
     */
    private final class Worker
        extends AbstractQueuedSynchronizer
        implements Runnable
    {
        /**
         * This class will never be serialized, but we provide a
         * serialVersionUID to suppress a javac warning.
         */
        private static final long serialVersionUID = 6138294804551838833L;

        /** 工作线程 */
        final Thread thread;
        /** 工作线程需要执行的第一个任务,通常是从工作队列中取出来的。默认为空 */
        Runnable firstTask;
        /** 线程的计数器*/
        volatile long completedTasks;

        /**
         *构造方法
         */
        Worker(Runnable firstTask) {
            //
            setState(-1); // 禁止中断
            this.firstTask = firstTask;
            //初始化一个工作线程
            this.thread = getThreadFactory().newThread(this);
        }

        /* 执行 */
        public void run() {
            runWorker(this);
        }

        // Lock methods
        //
        // The value 0 represents the unlocked state.
        // The value 1 represents the locked state.
        //判断是否已加锁 true为是 false 否
        protected boolean isHeldExclusively() {
            return getState() != 0;
        }
        //尝试获取锁
        protected boolean tryAcquire(int unused) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }
        //尝试释放锁
        protected boolean tryRelease(int unused) {
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }
        //加锁
        public void lock()        { acquire(1); }
        //尝试加锁
        public boolean tryLock()  { return tryAcquire(1); }
        //解锁
        public void unlock()      { release(1); }
        //判断是否锁住方法 true为是 false为否
        public boolean isLocked() { return isHeldExclusively(); }
        //中断方法
        void interruptIfStarted() {
            Thread t;
            if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
                try {
                    t.interrupt();
                } catch (SecurityException ignore) {
                }
            }
        }
    }

    /*
     * Methods for setting control state
     */

    //转换指定状态
    private void advanceRunState(int targetState) {
        for (;;) {
            int c = ctl.get();
            if (runStateAtLeast(c, targetState) ||
                ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
                break;
        }
    }

    //如果(关闭且池和队列为空)或(停止且池为空),则转换为终止状态。
    final void tryTerminate() {
        for (;;) {
            int c = ctl.get();
            //判断是否运行 或 结束状态 或 (关闭且死亡) 则直接返回
            if (isRunning(c) ||
                runStateAtLeast(c, TIDYING) ||
                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
                return;
            //非终止,则直接终止
            if (workerCountOf(c) != 0) { // Eligible to terminate
                interruptIdleWorkers(ONLY_ONE);
                return;
            }
            //上锁(重入锁)
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                //cas锁
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                    try {
                        //中断
                        terminated();
                    } finally {
                        //最终设置状态
                        ctl.set(ctlOf(TERMINATED, 0));
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                //解锁
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }

    /*
     * Methods for controlling interrupts to worker threads.
     */

    //如果有安全管理器,请确保调用方通常有权关闭线程
    private void checkShutdownAccess() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(shutdownPerm);
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                for (Worker w : workers)
                    security.checkAccess(w.thread);
            } finally {
                mainLock.unlock();
            }
        }
    }

    /**
     * 中断所有线程方法
     */
    private void interruptWorkers() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers)
                w.interruptIfStarted();
        } finally {
            mainLock.unlock();
        }
    }

    /**
     * 中断可能正在等待任务的线程
     */
    private void interruptIdleWorkers(boolean onlyOne) {
        //重入锁
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers) {
                Thread t = w.thread;
                if (!t.isInterrupted() && w.tryLock()) {
                    try {
                        t.interrupt();
                    } catch (SecurityException ignore) {
                    } finally {
                        w.unlock();
                    }
                }
                if (onlyOne)
                    break;
            }
        } finally {
            //解锁
            mainLock.unlock();
        }
    }

   //中断所有线程方法
    private void interruptIdleWorkers() {
        interruptIdleWorkers(false);
    }

    private static final boolean ONLY_ONE = true;

    /*
     * Misc utilities, most of which are also exported to
     * ScheduledThreadPoolExecutor
     */

    /**
     * 调用给定命令的拒绝执行处理程序。
     */
    final void reject(Runnable command) {
        handler.rejectedExecution(command, this);
    }

    /**
     * 关闭方法(空实现)
     */
    void onShutdown() {
    }

    /**
     * 判断关机或启动的方法
     */
    final boolean isRunningOrShutdown(boolean shutdownOK) {
        int rs = runStateOf(ctl.get());
        return rs == RUNNING || (rs == SHUTDOWN && shutdownOK);
    }

    /**
        将任务挪到新表中
     */
    private List<Runnable> drainQueue() {
        BlockingQueue<Runnable> q = workQueue;
        ArrayList<Runnable> taskList = new ArrayList<Runnable>();
        q.drainTo(taskList);
        if (!q.isEmpty()) {
            for (Runnable r : q.toArray(new Runnable[0])) {
                if (q.remove(r))
                    taskList.add(r);
            }
        }
        return taskList;
    }

    /*
     * Methods for creating, running and cleaning up after workers
     */

    /**
     * 检查是否可以根据当前池状态和给定边界(核心或最大)添加新工作线程。
     */
    private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN &&
                ! (rs == SHUTDOWN &&
                   firstTask == null &&
                   ! workQueue.isEmpty()))
                return false;

            for (;;) {
                int wc = workerCountOf(c);
                if (wc >= CAPACITY ||
                    wc >= (core ? corePoolSize : maximumPoolSize))
                    return false;
                if (compareAndIncrementWorkerCount(c))
                    break retry;
                c = ctl.get(); // Re-read ctl
                if (runStateOf(c) != rs)
                    continue retry;
                // else CAS failed due to workerCount change; retry inner loop
            }
        }

        boolean workerStarted = false;
        boolean workerAdded = false;
        Worker w = null;
        try {
            w = new Worker(firstTask);
            final Thread t = w.thread;
            if (t != null) {
                final ReentrantLock mainLock = this.mainLock;
                mainLock.lock();
                try {
                    // Recheck while holding lock.
                    // Back out on ThreadFactory failure or if
                    // shut down before lock acquired.
                    int rs = runStateOf(ctl.get());

                    if (rs < SHUTDOWN ||
                        (rs == SHUTDOWN && firstTask == null)) {
                        if (t.isAlive()) // precheck that t is startable
                            throw new IllegalThreadStateException();
                        workers.add(w);
                        int s = workers.size();
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                if (workerAdded) {
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }

    /**
     * 用于工作线程回滚的方法
     */
    private void addWorkerFailed(Worker w) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            if (w != null)
                workers.remove(w);
            decrementWorkerCount();
            tryTerminate();
        } finally {
            mainLock.unlock();
        }
    }

    //从队列中删除线程
    private void processWorkerExit(Worker w, boolean completedAbruptly) {
        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
            decrementWorkerCount();

        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            completedTaskCount += w.completedTasks;
            workers.remove(w);
        } finally {
            mainLock.unlock();
        }

        tryTerminate();

        int c = ctl.get();
        if (runStateLessThan(c, STOP)) {
            if (!completedAbruptly) {
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                if (workerCountOf(c) >= min)
                    return; // replacement not needed
            }
            addWorker(null, false);
        }
    }

    //获取一个任务
    private Runnable getTask() {
        boolean timedOut = false; // Did the last poll() time out?

        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                decrementWorkerCount();
                return null;
            }

            int wc = workerCountOf(c);

            // Are workers subject to culling?
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

            if ((wc > maximumPoolSize || (timed && timedOut))
                && (wc > 1 || workQueue.isEmpty())) {
                if (compareAndDecrementWorkerCount(c))
                    return null;
                continue;
            }

            try {
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();
                if (r != null)
                    return r;
                timedOut = true;
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
    }

    /**
     * 主工作线程运行循环
     *
     * 1.我们可能会从初始任务开始,在这种情况下,我们不需要获得第一个任务。
     *
     * 2.在运行任何任务之前,获取锁以防止在执行任务时发生其他池中断,然后我们确保除非池停止,否则该线程没有设置其中断。
     *
     * 3. Each task run is preceded by a call to beforeExecute, which
     * might throw an exception, in which case we cause thread to die
     * (breaking loop with completedAbruptly true) without processing
     * the task.
     *
     * 4.任务完成进行收集任务的处理
     *
     * 5. 任务执行完成后,调用 afterExecute,这也可能会抛出异常,这也会导致线程死亡。
     *
     * The net effect of the exception mechanics is that afterExecute
     * and the thread's UncaughtExceptionHandler have as accurate
     * information as we can provide about any problems encountered by
     * user code.
     *
     * @param w the worker
     */
    final void runWorker(Worker w) {
        //获取当前线程
        Thread wt = Thread.currentThread();
        //获取第一个任务
        Runnable task = w.firstTask;
        w.firstTask = null;
        //解锁(允许中断)
        w.unlock(); // allow interrupts
        //最终退出使用
        boolean completedAbruptly = true;
        try {
            //循环从队列中获取一个线程
            while (task != null || (task = getTask()) != null) {
                //上锁
                w.lock();
                // If pool is stopping, ensure thread is interrupted;
                // if not, ensure thread is not interrupted. This
                // requires a recheck in second case to deal with
                // shutdownNow race while clearing interrupt
                //判断是需要中断
                if ((runStateAtLeast(ctl.get(), STOP) ||
                     (Thread.interrupted() &&
                      runStateAtLeast(ctl.get(), STOP))) &&
                    !wt.isInterrupted())
                    wt.interrupt();
                try {
                    //执行task的方法
                    beforeExecute(wt, 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);
        }
    }

    // Public constructors and methods

    //构造方法带参
    //corePoolSize 核心数
    //maximumPoolSize 最大线程数量
    //keepAliveTime 超时时间
    //TimeUnit 时间单位
    //BlockingQueue 执行队列任务
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

    //同上类似
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }

    //同上类似
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), handler);
    }


    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

    //提交执行任务(异步的)
    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        /*
         *
         *分 3 个步骤进行:
                1. 如果正在运行的线程少于 corePoolSize,尝试使用给定命令作为其第一个任务来启动新线程。
                对 addWorker 的调用以原子方式检查 runState 和 workerCount,通过返回 false 来防止错误警报,这些警报会在空闲添加线程。
                2. 如果一个任务可以成功排队,那么仍然需要仔细检查我们是否应该添加一个线程(因为现有线程自上次检查以来就死了)或者池在进入此方法后关闭了。
                重新检查状态,如有必要,如果停止,则回滚排队,如果没有,则启动一个新线程。
                3.如果不能排队任务,那么尝试添加一个新线程。如果失败了,要么是已经关闭或饱和,因此拒绝这项任务。
         Proceed in 3 steps:

        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }

    //关闭线程池(无返回)
    public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            advanceRunState(SHUTDOWN);
            interruptIdleWorkers();
            onShutdown(); // hook for ScheduledThreadPoolExecutor
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
    }

    //关闭线程池(并返回等待执行的任务的列表。)
    public List<Runnable> shutdownNow() {
        List<Runnable> tasks;
        //逻辑是上锁然后获取列表,最后返回
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            advanceRunState(STOP);
            interruptWorkers();
            tasks = drainQueue();
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
        return tasks;
    }
    //判断当前是否关闭 true是 false否
    public boolean isShutdown() {
        return ! isRunning(ctl.get());
    }

    //判断是否未完全停止(正在关机中)
    public boolean isTerminating() {
        int c = ctl.get();
        return ! isRunning(c) && runStateLessThan(c, TERMINATED);
    }
    //判断线程是否已终止
    public boolean isTerminated() {
        return runStateAtLeast(ctl.get(), TERMINATED);
    }
    //带超时时间终止方法
    public boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException {
        long nanos = unit.toNanos(timeout);
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (;;) {
                if (runStateAtLeast(ctl.get(), TERMINATED))
                    return true;
                if (nanos <= 0)
                    return false;
                nanos = termination.awaitNanos(nanos);
            }
        } finally {
            mainLock.unlock();
        }
    }

    //关闭方法
    protected void finalize() {
        SecurityManager sm = System.getSecurityManager();
        if (sm == null || acc == null) {
            shutdown();
        } else {
            PrivilegedAction<Void> pa = () -> { shutdown(); return null; };
            AccessController.doPrivileged(pa, acc);
        }
    }

    //设置用于创建新线程的线程工厂。
    public void setThreadFactory(ThreadFactory threadFactory) {
        if (threadFactory == null)
            throw new NullPointerException();
        this.threadFactory = threadFactory;
    }

   //获取线程工厂
    public ThreadFactory getThreadFactory() {
        return threadFactory;
    }

    //为不可执行的任务设置新的处理程序。
    public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
        if (handler == null)
            throw new NullPointerException();
        this.handler = handler;
    }

    /**
     * 返回不可执行任务的当前处理程序。
     *
     * @return the current handler
     * @see #setRejectedExecutionHandler(RejectedExecutionHandler)
     */
    public RejectedExecutionHandler getRejectedExecutionHandler() {
        return handler;
    }

    /**
     * 设置线程的核心数。
     *
     * @param corePoolSize the new core size
     * @throws IllegalArgumentException if {@code corePoolSize < 0}
     * @see #getCorePoolSize
     */
    public void setCorePoolSize(int corePoolSize) {
        if (corePoolSize < 0)
            throw new IllegalArgumentException();
        int delta = corePoolSize - this.corePoolSize;
        this.corePoolSize = corePoolSize;
        if (workerCountOf(ctl.get()) > corePoolSize)
            interruptIdleWorkers();
        else if (delta > 0) {
            // We don't really know how many new threads are "needed".
            // As a heuristic, prestart enough new workers (up to new
            // core size) to handle the current number of tasks in
            // queue, but stop if queue becomes empty while doing so.
            int k = Math.min(delta, workQueue.size());
            while (k-- > 0 && addWorker(null, true)) {
                if (workQueue.isEmpty())
                    break;
            }
        }
    }

    /**
     * Returns the core number of threads.
     *
     * @return the core number of threads
     * @see #setCorePoolSize
     */
    public int getCorePoolSize() {
        return corePoolSize;
    }

    /**
     *启动核心线程,使其空闲等待工作。
     *
     * @return {@code true} if a thread was started
     */
    public boolean prestartCoreThread() {
        return workerCountOf(ctl.get()) < corePoolSize &&
            addWorker(null, true);
    }

    /**
     * Same as prestartCoreThread except arranges that at least one
     * thread is started even if corePoolSize is 0.
     */
    void ensurePrestart() {
        int wc = workerCountOf(ctl.get());
        if (wc < corePoolSize)
            addWorker(null, true);
        else if (wc == 0)
            addWorker(null, false);
    }

    /**
     * 启动所有核心线程
     *
     * @return the number of threads started
     */
    public int prestartAllCoreThreads() {
        int n = 0;
        while (addWorker(null, true))
            ++n;
        return n;
    }

    /**
     * 如果此线程池允许核心线程超时,则返回 true。
       如果 keepAlive 时间内没有任务到达,则返回 true
       如果需要,在新任务到达时替换。
     *
     * @return {@code true} if core threads are allowed to time out,
     * else {@code false}
     *
     * @since 1.6
     */
    public boolean allowsCoreThreadTimeOut() {
        return allowCoreThreadTimeOut;
    }

    //同上类似
    public void allowCoreThreadTimeOut(boolean value) {
        if (value && keepAliveTime <= 0)
            throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
        if (value != allowCoreThreadTimeOut) {
            allowCoreThreadTimeOut = value;
            if (value)
                interruptIdleWorkers();
        }
    }

    //设置最大的线程核心数
    public void setMaximumPoolSize(int maximumPoolSize) {
        if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
            throw new IllegalArgumentException();
        this.maximumPoolSize = maximumPoolSize;
        if (workerCountOf(ctl.get()) > maximumPoolSize)
            interruptIdleWorkers();
    }

    /**
     * Returns the maximum allowed number of threads.
     *
     * @return the maximum allowed number of threads
     * @see #setMaximumPoolSize
     */
    public int getMaximumPoolSize() {
        return maximumPoolSize;
    }

    //设置线程空闲超时时间
    public void setKeepAliveTime(long time, TimeUnit unit) {
        if (time < 0)
            throw new IllegalArgumentException();
        if (time == 0 && allowsCoreThreadTimeOut())
            throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
        long keepAliveTime = unit.toNanos(time);
        long delta = keepAliveTime - this.keepAliveTime;
        this.keepAliveTime = keepAliveTime;
        if (delta < 0)
            interruptIdleWorkers();
    }

    //获取空间时间(这个单位有点坑,没用到 )
    public long getKeepAliveTime(TimeUnit unit) {
        return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
    }

    /* User-level queue utilities */

    //返回执行任务队列
    public BlockingQueue<Runnable> getQueue() {
        return workQueue;
    }

    //删除任务方法
    public boolean remove(Runnable task) {
        boolean removed = workQueue.remove(task);
        tryTerminate(); // In case SHUTDOWN and now empty
        return removed;
    }

    //尝试从工作队列中删除所有已取消任务
    public void purge() {
        final BlockingQueue<Runnable> q = workQueue;
        try {
            Iterator<Runnable> it = q.iterator();
            //遍历查找
            while (it.hasNext()) {
                Runnable r = it.next();
                if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
                    it.remove();
            }
        } catch (ConcurrentModificationException fallThrough) {
            // Take slow path if we encounter interference during traversal.
            // Make copy for traversal and call remove for cancelled entries.
            // The slow path is more likely to be O(N*N).
            for (Object r : q.toArray())
                if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
                    q.remove(r);
        }

        tryTerminate(); // In case SHUTDOWN and now empty
    }

    /* Statistics */

    //返回池中的当前线程数。
    public int getPoolSize() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            // Remove rare and surprising possibility of
            // isTerminated() && getPoolSize() > 0
            return runStateAtLeast(ctl.get(), TIDYING) ? 0
                : workers.size();
        } finally {
            mainLock.unlock();
        }
    }

    //返回存活线程数
    public int getActiveCount() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            int n = 0;
            for (Worker w : workers)
                if (w.isLocked())
                    ++n;
            return n;
        } finally {
            mainLock.unlock();
        }
    }

   //返回最大线程数
    public int getLargestPoolSize() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            return largestPoolSize;
        } finally {
            mainLock.unlock();
        }
    }

    //返回当前任务数
    public long getTaskCount() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            long n = completedTaskCount;
            for (Worker w : workers) {
                n += w.completedTasks;
                if (w.isLocked())
                    ++n;
            }
            return n + workQueue.size();
        } finally {
            mainLock.unlock();
        }
    }

    //返回已完成执行的任务的大致总数。
    public long getCompletedTaskCount() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            long n = completedTaskCount;
            for (Worker w : workers)
                n += w.completedTasks;
            return n;
        } finally {
            mainLock.unlock();
        }
    }


    public String toString() {
        long ncompleted;
        int nworkers, nactive;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            ncompleted = completedTaskCount;
            nactive = 0;
            nworkers = workers.size();
            for (Worker w : workers) {
                ncompleted += w.completedTasks;
                if (w.isLocked())
                    ++nactive;
            }
        } finally {
            mainLock.unlock();
        }
        int c = ctl.get();
        String rs = (runStateLessThan(c, SHUTDOWN) ? "Running" :
                     (runStateAtLeast(c, TERMINATED) ? "Terminated" :
                      "Shutting down"));
        return super.toString() +
            "[" + rs +
            ", pool size = " + nworkers +
            ", active threads = " + nactive +
            ", queued tasks = " + workQueue.size() +
            ", completed tasks = " + ncompleted +
            "]";
    }

    /* Extension hooks */

    /**
     * Method invoked prior to executing the given Runnable in the
     * given thread. This method is invoked by thread {@code t} that
     * will execute task {@code r}, and may be used to re-initialize
     * ThreadLocals, or to perform logging.
     *
     * <p>This implementation does nothing, but may be customized in
     * subclasses. Note: To properly nest multiple overridings, subclasses
     * should generally invoke {@code super.beforeExecute} at the end of
     * this method.
     *
     * @param t the thread that will run task {@code r}
     * @param r the task that will be executed
     */
    protected void beforeExecute(Thread t, Runnable r) { }

    /**
     * Method invoked upon completion of execution of the given Runnable.
     * This method is invoked by the thread that executed the task. If
     * non-null, the Throwable is the uncaught {@code RuntimeException}
     * or {@code Error} that caused execution to terminate abruptly.
     *
     * <p>This implementation does nothing, but may be customized in
     * subclasses. Note: To properly nest multiple overridings, subclasses
     * should generally invoke {@code super.afterExecute} at the
     * beginning of this method.
     *
     * <p><b>Note:</b> When actions are enclosed in tasks (such as
     * {@link FutureTask}) either explicitly or via methods such as
     * {@code submit}, these task objects catch and maintain
     * computational exceptions, and so they do not cause abrupt
     * termination, and the internal exceptions are <em>not</em>
     * passed to this method. If you would like to trap both kinds of
     * failures in this method, you can further probe for such cases,
     * as in this sample subclass that prints either the direct cause
     * or the underlying exception if a task has been aborted:
     *
     * <pre> {@code
     * class ExtendedExecutor extends ThreadPoolExecutor {
     * // ...
     * protected void afterExecute(Runnable r, Throwable t) {
     * super.afterExecute(r, t);
     * if (t == null && r instanceof Future<?>) {
     * try {
     * Object result = ((Future<?>) r).get();
     * } catch (CancellationException ce) {
     * t = ce;
     * } catch (ExecutionException ee) {
     * t = ee.getCause();
     * } catch (InterruptedException ie) {
     * Thread.currentThread().interrupt(); // ignore/reset
     * }
     * }
     * if (t != null)
     * System.out.println(t);
     * }
     * }}</pre>
     *
     * @param r the runnable that has completed
     * @param t the exception that caused termination, or null if
     * execution completed normally
     */
    protected void afterExecute(Runnable r, Throwable t) { }

    /**
     * Method invoked when the Executor has terminated. Default
     * implementation does nothing. Note: To properly nest multiple
     * overridings, subclasses should generally invoke
     * {@code super.terminated} within this method.
     */
    protected void terminated() { }

    /* Predefined RejectedExecutionHandlers */

    /**
     * A handler for rejected tasks that runs the rejected task
     * directly in the calling thread of the {@code execute} method,
     * unless the executor has been shut down, in which case the task
     * is discarded.
     */
    public static class CallerRunsPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code CallerRunsPolicy}.
         */
        public CallerRunsPolicy() { }

        /**
         * Executes task r in the caller's thread, unless the executor
         * has been shut down, in which case the task is discarded.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                r.run();
            }
        }
    }

    /**
     * 拒绝任务的处理程序,该处理程序引发
     * {@code RejectedExecutionException}.
     */
    public static class AbortPolicy implements RejectedExecutionHandler {
        /**
         * Creates an {@code AbortPolicy}.
         */
        public AbortPolicy() { }

        /**
         * Always throws RejectedExecutionException.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         * @throws RejectedExecutionException always
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }
    }

    /**
     * 以静默方式丢弃被拒绝的任务的处理程序。
     */
    public static class DiscardPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code DiscardPolicy}.
         */
        public DiscardPolicy() { }

        /**
         * Does nothing, which has the effect of discarding task r.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        }
    }

    /**
     * 被拒绝任务的处理程序,它丢弃最早的未处理请求,
     */
    public static class DiscardOldestPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code DiscardOldestPolicy} for the given executor.
         */
        public DiscardOldestPolicy() { }

        /**
         * Obtains and ignores the next task that the executor
         * would otherwise execute, if one is immediately available,
         * and then retries execution of task r, unless the executor
         * is shut down, in which case task r is instead discarded.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                e.getQueue().poll();
                e.execute(r);
            }
        }
    }
}

线程池原理

fd4f796f7d1151c83a24799d60cee4b9.png

执行流程:

  • 当执行任务数<核心线程数量(corePoolSize),则创建一个新线程来执行。

  • 当执行任务数>=核心线程数量(corePoolSize),线程池内的阻塞队列未满,则将任务添加到该阻塞队列中;

  • 当执行任务数>=核心线程数量(corePoolSize)且 当执行任务数<线程池最大线程数量,线程池内的阻塞阶列已满,创建新线程来执行;

  • 当执行任务数>=核心线程数量(corePoolSize),线程池内的阻塞阶列已满,则根据拒绝策略来处理该任务, 默认的处理方式是直接抛异常。

execute的执行流程:

b2766ba115f1424c2f16447efd9495f9.png

最后

    如果系统中有很多的线程要使用建议使用线程池,避免因为手动new的线程导致系统一些不稳定性因素出现,特别可以利用线程池来管理和保障系统的稳定性,当然具体怎么调,建议参考《阿里巴巴开发手册》。

本文仅写了ThreadPoolExecutor有部分源码没有深入去写注释,有需要详细的同学可再深入或私下交流。

参考文献

    https://zhuanlan.zhihu.com/p/505594640

猜你喜欢

转载自blog.csdn.net/qq_16498553/article/details/129543660
今日推荐