线程池参数

1,线程池创建

import java.util.concurrent.ThreadPoolExecutor;

ThreadPoolExecutor threadPool = new ThreadPoolExecutor(7个参数);

 

2,线程池参数介绍

  int corePoolSize:核心线程数;

  int maximumPoolSize:最大线程数;

  long keepAliveTime:线程空闲的存活时间;

  TimeUnit unit:空闲时存活时间的单位,秒分时天月等;

  BlockingQueue<Runnable> workQueue:工作队列;

  ThreadFactory threadFactory:创建线程的工厂;

  RejectedExecutionHandler handler:拒绝策略;


3,测试

3.1,需要执行的任务

public class MyTask implements Runnable {
    /**
     * 标识当前任务的序号
     */
    private int no;

    public MyTask(int no) {
        this.no = no;
    }

    @Override
    public void run() {
        System.out.println(String.format("任务" + no + "开始执行,当前时间:" + MyUtil.getCurrentChineseTime(new Date())));
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            throw new RuntimeException("任务" + no + "在sleep时出错啦");
        }
        System.out.println("任务" + no + "完成,当前时间:" + MyUtil.getCurrentChineseTime(new Date()));
    }
}

3.2,创建线程池,并执行10个任务

        /**
         * 1,核心线程数:2
         * 2,最大线程数:4
         * 3,非核心线程空闲时的存活时间:1秒
         * 4,非核心线程空闲时的存活时间单位:秒
         * 5,工作队列:有界队列(FIFO,界限为3,即最多缓存3个任务)
         * 6,创建线程的工厂:此处为默认工厂Executors.defaultThreadFactory()
         * 7,拒绝策略:此处为默认拒绝策略defaultHandler,即new AbortPolicy(),直接丢弃任务并抛出RejectedExecutionException异常
         */
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 1, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3));

        // 创建10个待执行的任务,任务序号0-9
        List<MyTask> myTaskList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            MyTask myTask = new MyTask(i);
            myTaskList.add(myTask);
        }

        // 同步(同时)执行任务0-任务9
        for (MyTask myTask : myTaskList) {
            threadPool.execute(myTask);
        }

3.3,运行结果

Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task com.learnjava.threadPool.threadpool.MyTask@5451c3a8 rejected from java.util.concurrent.ThreadPoolExecutor@2626b418[Running, pool size = 4, active threads = 4, queued tasks = 3, completed tasks = 0]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
at com.learnjava.threadPool.threadpool.ThreadPoolLearn.main(ThreadPoolLearn.java:31)
任务1开始执行,当前时间:2024-02-16 17:19:30
任务6开始执行,当前时间:2024-02-16 17:19:30
任务0开始执行,当前时间:2024-02-16 17:19:30
任务5开始执行,当前时间:2024-02-16 17:19:30
任务0完成,当前时间:2024-02-16 17:19:32
任务5完成,当前时间:2024-02-16 17:19:32
任务1完成,当前时间:2024-02-16 17:19:32
任务2开始执行,当前时间:2024-02-16 17:19:32
任务6完成,当前时间:2024-02-16 17:19:32
任务3开始执行,当前时间:2024-02-16 17:19:32
任务4开始执行,当前时间:2024-02-16 17:19:32
任务2完成,当前时间:2024-02-16 17:19:34
任务3完成,当前时间:2024-02-16 17:19:34
任务4完成,当前时间:2024-02-16 17:19:34

3.4,结果分析

任务0到任务9同时交给线程池处理,线程池大差不差按时间先后顺序执行如下:

一、线程池创建了2个核心线程执行任务1、任务6;

二、线程池将任务2、任务3、任务4放进了工作队列中,等待执行;

三、线程池创建2个非核心线程执行任务0、任务5;

四、线程池开始处理任务7,但是此时没有空闲线程,4个线程(2个核心线程和2个非核心线程)都在执行任务中,且工作队列已经满了(只能放3个任务),所以执行拒绝策略,预定的策略是直接丢弃且抛出RejectedExecutionException异常;任务8、任务9同理;

五、差不多2秒(任务时间为2秒)后,线程池中的4个线程其中有个执行完成了,则取出队列中的第一个任务(此处认为是任务2)执行,同理有线程空闲了就取出工作队列中的其他两个任务(任务3、任务4)执行;

六、非核心线程,处于空闲状态,时间达到设定的空闲时间时会销毁(或其他操作以节约资源)。

 

4,总结

先创建核心线程执行任务,核心线程数没到时,即使之前创建的核心线程空闲了也会继续创建核心线程执行新任务,直到核心线程的数量达到核心线程数;

核心线程数到了时,核心线程会一直存活;即使空闲也不会直接执行新任务,要等新任务加入工作队列后,才从工作队列取出来执行;

工作队列满了后,会创建非核心线程来执行新任务,核心线程数量+非核心线程数量不能超过总数,超过后执行拒绝策略;

 

看下debug的情况:

4.1,创建核心线程

 

4.2,任务加入工作队列

 

 4.3,debug总结

a,核心线程数量没到时,即使之前创建的核心线程空闲了,也会重新创建一个核心线程来执行任务,不会使用之前创建的核心线程来执行;

b,核心线程到数量后,会一直存活,即使空闲了也不会直接执行新任务,而是等到新任务加入到工作队里后从队列里面取出来执行;

 

posted @ 2024-02-16 21:33  seeAll  阅读(173)  评论(0编辑  收藏  举报