java_线程池7大参数_底层运行原理

int corePoolSize:线程池中常驻的核心线程数;

int maximumPoolSize:线程池中能够容纳同时执行的最大线程数,此值必须大于等于1;

long keepAliveTime:多余的空闲线程的存活时间,当前线程池数量超过corePoolSize的时候,

           当空闲时间达到keepAliveTime值时,多余空闲线程会被销毁,直到只剩下corePoolSize个线程为止;

TimeUnit unitkeepAliveTime的单位;

BlockingQueue<Runnable> workQueue:任务队列(阻塞队列),被提交但尚未被执行的任务处处于阻塞队列中;

ThreadFactory threadFactory:表示生产线程池中工作线程的线程工厂,用于创建线程,一般用默认的即可

RejectedExecutionHandler handler:拒绝策略,当队列满了,并且工作线程大于等于线程池的最大线程数(maximumPoolSize);

 

 

 

 

RejectedExecutionHandler handler:四种拒绝策略:

AbortPolicy(默认):直接抛出RejectedExecutionException阻止系统正常运行;

CallerRunsPolicy:“调用者模式”,一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某个任务回退到调用者,从而降低新任务的流量;

DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务;

DiscardPolicy:直接丢弃任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的一种方案;

 

注意:

再生产环境下,三种常见创建线程池的方法都不会去使用,通常是自定义创建一个线程池;

        ExecutorService threadPool = new ThreadPoolExecutor(
                2,//当前线程池常驻线程数
                5,//当前线程池最大线程数
                1L,//当前线程池线程数大于corePoolSize时,空闲线程数经过当前时间后被销毁,知道线程数为corePoolSize
                TimeUnit.SECONDS,//空闲线程销毁等待时间keepAliveTime的单位
                new LinkedBlockingDeque<>(3),//阻塞队列,长度为3
                Executors.defaultThreadFactory(),//生产线程的工厂,通常使用默认的
                new ThreadPoolExecutor.AbortPolicy());//拒绝策略,AbortPolicy()默认的

示例代码如下:

import java.util.concurrent.*;

//线程池
public class MyThreadPoolDemo {
    public static void main(String[] args) {
        ExecutorService threadPool = new ThreadPoolExecutor(
                2,//当前线程池常驻线程数
                5,//当前线程池最大线程数
                1L,//当前线程池线程数大于corePoolSize时,空闲线程数经过当前时间后被销毁,知道线程数为corePoolSize
                TimeUnit.SECONDS,//空闲线程销毁等待时间keepAliveTime的单位
                new LinkedBlockingDeque<>(3),//阻塞队列,长度为3
                Executors.defaultThreadFactory(),//生产线程的工厂,通常使用默认的
                new ThreadPoolExecutor.AbortPolicy());//拒绝策略,AbortPolicy()默认的

        try {
            //模拟10个用户办理业务
            for (int i = 1; i <= 10; i++) {
                threadPool.execute(() ->{
                    System.out.println(Thread.currentThread().getName()+"\t 办理业务");
                });
                //TimeUnit.SECONDS.sleep(1);//每一秒钟只有一个人来办理业务
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            threadPool.shutdown();
        }
    }
}

 

更改线程池如下:

        ExecutorService threadPool = new ThreadPoolExecutor(
                2,//当前线程池常驻线程数
                5,//当前线程池最大线程数
                1L,//当前线程池线程数大于corePoolSize时,空闲线程数经过当前时间后被销毁,知道线程数为corePoolSize
                TimeUnit.SECONDS,//空闲线程销毁等待时间keepAliveTime的单位
                new LinkedBlockingDeque<>(3),//阻塞队列,长度为3
                Executors.defaultThreadFactory(),//生产线程的工厂,通常使用默认的
                new ThreadPoolExecutor.CallerRunsPolicy());//拒绝策略,AbortPolicy()默认的

 

更改线程池如下:

        ExecutorService threadPool = new ThreadPoolExecutor(
                2,//当前线程池常驻线程数
                5,//当前线程池最大线程数
                1L,//当前线程池线程数大于corePoolSize时,空闲线程数经过当前时间后被销毁,知道线程数为corePoolSize
                TimeUnit.SECONDS,//空闲线程销毁等待时间keepAliveTime的单位
                new LinkedBlockingDeque<>(3),//阻塞队列,长度为3
                Executors.defaultThreadFactory(),//生产线程的工厂,通常使用默认的
                new ThreadPoolExecutor.DiscardOldestPolicy());//拒绝策略,AbortPolicy()默认的

 

更改线程池如下:

        ExecutorService threadPool = new ThreadPoolExecutor(
                2,//当前线程池常驻线程数
                5,//当前线程池最大线程数
                1L,//当前线程池线程数大于corePoolSize时,空闲线程数经过当前时间后被销毁,知道线程数为corePoolSize
                TimeUnit.SECONDS,//空闲线程销毁等待时间keepAliveTime的单位
                new LinkedBlockingDeque<>(3),//阻塞队列,长度为3
                Executors.defaultThreadFactory(),//生产线程的工厂,通常使用默认的
                new ThreadPoolExecutor.DiscardPolicy());//拒绝策略,AbortPolicy()默认的

 

线程池中最大线程数应该如何配置:

CPU密集型(需要大量的运算)

IO密集型:

第一种情况:

 

第二种情况:

 

posted @ 2021-03-11 16:53  DHaiLin  阅读(120)  评论(0编辑  收藏  举报