• ThreadPoolExecutor构造函数重要参数分析,以及创建线程池


    参数分析

    ThreadPoolExecutor构造方法

    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;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    1. 参数分析
    • corePoolSize : 核心线程数定义了最小可以同时运行的线程数量。
    • maximumPoolSize : 当队列中存放的任务达到队列容量的时候,当前可以同时运行的线程数量变为最大线程数。
    • workQueue: 当新任务来的时候会先判断当前运行的线程数量是否达到核心线程数,如果达到的话,新任务就会被存放在队列中。

    ThreadPoolExecutor其他常见参数:

    • keepAliveTime:当线程池中的线程数量大于
    • corePoolSize 的时候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过了 keepAliveTime才会被回收销毁;
    • unit : keepAliveTime 参数的时间单位。
    • threadFactory :executor 创建新线程的时候会用到
    • handler :饱和策略
      • ThreadPoolExecutor.AbortPolicy: 抛出 RejectedExecutionException来拒绝新任务的处理。
      • ThreadPoolExecutor.CallerRunsPolicy: 调用执行自己的线程运行任务,也就是直接在调用execute方法的线程中运行(run)被拒绝的任务,如果执行程序已关闭,则会丢弃该任务。因此这种策略会降低对于新任务提交速度,影响程序的整体性能。如果您的应用程序可以承受此延迟并且你要求任何一个任务请求都要被执行的话,你可以选择这个策略。
      • ThreadPoolExecutor.DiscardPolicy: 不处理新任务,直接丢弃掉。
      • ThreadPoolExecutor.DiscardOldestPolicy: 此策略将丢弃最早的未处理的任务请求。

    创建简单线程池Demo

    MyRunnable.java

    package ThreadPoolExecutorDemo;
    
    import java.util.Date;
    
    //创建一个简单的Runnable类,需要大约5s中来执行其任务
    public class MyRunnable implements Runnable{
        private String command;
        public MyRunnable(String s){
            this.command = s;
        }
    
        @Override
        public void run(){
            System.out.println(Thread.currentThread().getName() + " start. Time = " + new Date());
            processCommand();
            System.out.println(Thread.currentThread().getName() + " End. Time = " + new Date());
        }
        
        private void processCommand(){
            try{
                Thread.sleep(5000);
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    
        @Override 
        public String toString(){
            return this.command;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    测试ThreadPoolExecutorDemo.java

    corePoolSize: 核心线程数为 5。
    maximumPoolSize :最大线程数 10
    keepAliveTime : 等待时间为 1L。
    unit: 等待时间的单位为 TimeUnit.SECONDS。
    workQueue:任务队列为 ArrayBlockingQueue,并且容量为 100;
    handler:饱和策略为 CallerRunsPolicy。

    package ThreadPoolExecutorDemo;
    
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    public class ThreadPoolExecutorDemo {
        private static final int CORE_POOL_SIZE = 5;
        private static final int MAX_POOL_SIZE = 10;
        private static final int QUEUE_CAPACITY = 100;
        private static final Long KEEP_ALIVE_TIME = 1L;
        public static void main(String[] args){
            //
            //
            ThreadPoolExecutor executor = new ThreadPoolExecutor(
                CORE_POOL_SIZE,
                MAX_POOL_SIZE,
                KEEP_ALIVE_TIME,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(QUEUE_CAPACITY),
                new ThreadPoolExecutor.CallerRunsPolicy()
            );
    
            for(int i = 0; i < 10; i++){
                Runnable worker = new MyRunnable("" + i);
                executor.execute(worker);
            }
    
            //
            executor.shutdown();
            while(!executor.isTerminated()){
            }
            System.out.println("Finished all threads");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    输出

    pool-1-thread-1 start. Time = Thu Aug 18 10:20:30 CST 2022
    pool-1-thread-3 start. Time = Thu Aug 18 10:20:30 CST 2022
    pool-1-thread-4 start. Time = Thu Aug 18 10:20:30 CST 2022
    pool-1-thread-2 start. Time = Thu Aug 18 10:20:30 CST 2022
    pool-1-thread-5 start. Time = Thu Aug 18 10:20:30 CST 2022
    pool-1-thread-1 End. Time = Thu Aug 18 10:20:35 CST 2022
    pool-1-thread-3 End. Time = Thu Aug 18 10:20:35 CST 2022
    pool-1-thread-4 End. Time = Thu Aug 18 10:20:35 CST 2022
    pool-1-thread-5 End. Time = Thu Aug 18 10:20:35 CST 2022
    pool-1-thread-2 End. Time = Thu Aug 18 10:20:35 CST 2022
    pool-1-thread-5 start. Time = Thu Aug 18 10:20:35 CST 2022
    pool-1-thread-4 start. Time = Thu Aug 18 10:20:35 CST 2022
    pool-1-thread-3 start. Time = Thu Aug 18 10:20:35 CST 2022
    pool-1-thread-1 start. Time = Thu Aug 18 10:20:35 CST 2022
    pool-1-thread-2 start. Time = Thu Aug 18 10:20:35 CST 2022
    pool-1-thread-3 End. Time = Thu Aug 18 10:20:40 CST 2022
    pool-1-thread-1 End. Time = Thu Aug 18 10:20:40 CST 2022
    pool-1-thread-5 End. Time = Thu Aug 18 10:20:40 CST 2022
    pool-1-thread-4 End. Time = Thu Aug 18 10:20:40 CST 2022
    pool-1-thread-2 End. Time = Thu Aug 18 10:20:40 CST 2022
    Finished all threads
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    流程图+解释

    在这里插入图片描述
    在代码中模拟了10个任务,配置的核心线程数为5,等待队列容量为100,所以每次只可能存在5个任务同时执行,剩下的5个任务会被放到等待队列中。当前的5个任务中如果有任务被执行完了,现成就会去拿新的任务去执行。

  • 相关阅读:
    vuex里的state,actions,mutations用法与理解
    现货白银图表分析的依据
    安科瑞余压监控系统
    沙箱机制的理解
    免费音频剪辑
    IDEA: 如何导入项目模块 以及 将 Java程序打包 JAR 详细步骤
    VMware之RAID配置
    SpringCloudAlibaba — — OpenFeign的简单应用
    Unity-Input System新输入系统插件学习
    STM32 基础学习——GPIO位结构(江科大老师教程)
  • 原文地址:https://blog.csdn.net/qq_41704415/article/details/126400621