22、7大参数自定义线程池(核心线程数,最大核心线程数。。。拒绝策略(4种))

7大参数自定义线程池(核心线程数,最大核心线程数。。。拒绝策略(4种))

第一步:我们首先看单例线程池的源码

第二步:多个固定线程的线程池源码

第三步:可变的线程数的线程池源码

开启线程池的本质(调用ThreadPoolExecutor())

进去调用的this,再往下走

!!!走this方法里(可以看到有7个参数)

*corePoolSize:核心线程数

*maximumPoolSize:最大核心线程池大小(是包括前面的核心线程数的。前面为2,设置为5,那么旁边就是剩3个封存着的)

*keepAliveTime:超时无人调用就会释放

*TimeUnit:超时单位

*BlockingQueue<Runnable>:阻塞队列

*ThreadFactory:线程工厂,创建线程的(一般不用动)

*RejectExecutionHandler:拒绝策略(有四种的)

分析源码:

因为我们这个若是用的Executors去创建线程池的话,那么可以看到这个CachedThreadPool可能会创建大量的线程(最多21亿)从而导致OOM

!!!7大参数模型:(这里也说下线程池的运行逻辑)

首先我们线程池里面有几个东西这样说吧,核心线程数,最大线程数(阻塞队列吗,满了才开启的),阻塞队列,拒绝策略。

  1. 我们我们有任务进来,先看下核心线程是否有空闲,若是有空闲就用空闲线程来执行2、若是核心线程数都被占用,那么就会将任务放到阻塞队列
  2. 若是阻塞队列都放满了,那么我们就使用最大线程数的线程来执行

4、若是最大线程数也满了,那就4种拒绝策略拒绝咯

代码操作:

Executors默认使用AborPolicy(不处理,抛出异常)

第一步:5个人进去(2个核心数处理,3个再阻塞队列里面,最大5个个核心线程数(3个在等待阻塞队列满了唤醒))

两个核心线程在使用

第二步:进去6个人(就会使用2个核心线程和,一个最大线程数里的了,(3个再阻塞队列里))

同理7个线程,就会触发线程池中4个线程数处理。

9个就会触发拒接策略了(这里是不处理,抛出异常(5+3)线程池最多容纳8个线程)

里面最多5个核心线程数跑,然后最多容纳8个,有一个就拒绝策略,这里是不处理抛出异常(.AbortPolicy())

!!!第二种拒绝策略:(CallerRunsPolicy(哪来的去哪里))这里我们是main线程创建的,所以就是main线程去处理

看到没有是main去处理的,滚回去让创建你的处理去(拒绝策略)5个最大核心线程+main线程

!!第三个拒绝策略(DisCarPolict(队列满了,丢掉任务(不处理)不会抛出异常))

这里看到,没有处理,也不会抛出异常

拒绝策略4、(DiscardOldestPolicy(队列满了,尝试和最早的线程竞争,竞争失败就不执行咯(不是直接不执行),也是不会抛出异常的(是我们DIs上面的升级版嘛)))

没有抛出异常,尝试和最早的线程竞争

 总结:

package org.example.threadpoolexecutor;



import java.util.concurrent.*;



public class TestThreadPoolSeven {

    public static void main(String[] args) {

        System.out.println(Runtime.getRuntime().availableProcessors());

        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(

                2,//核心线程是

                Runtime.getRuntime().availableProcessors(),//最大线程数

                0L,//超时多久没人调用会释放

                TimeUnit.MINUTES,//超时单位

                new LinkedBlockingDeque<>(3),//阻塞队列(大小为3)

                Executors.defaultThreadFactory(),//线程工厂,一般不会动

//                new ThreadPoolExecutor.AbortPolicy());//超过容量,不处理抛出异常

//                new ThreadPoolExecutor.CallerRunsPolicy());//超出容量,线程池不处理,返回给创建他的处理

//                new ThreadPoolExecutor.DiscardPolicy());//不处理,直接丢弃。不抛异常

                new ThreadPoolExecutor.DiscardOldestPolicy());//不直接抛弃,而是和最早的线程竞争线程

        try {

            for (int i = 1; i <=9; i++) {

                threadPool.execute(()->{

                    System.out.println(Thread.currentThread().getName()+"=>ok");

                });



            }

        } catch (Exception e) {

            throw new RuntimeException(e);

        } finally {

            threadPool.shutdown();

        }



猜你喜欢

转载自blog.csdn.net/logtcm4/article/details/127886874