Advertisement

线程池的七大参数及自定义线程池

阅读量:

上篇写了线程池三大方法,先回顾以下:

Executors.newSingleThreadExecutor(); 单线程

Executors.newFixedThreadPool(5); 固定线程个数

Executors.newCachedThreadPool(); 缓存池,可扩展

我们看“三大方法”的源码分析,这样才能更好理解“七大参数”:

复制代码
    //Executors.newSingleThreadExecutor(); 单线程
    //源码分析:
    public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
    }   
    
    //Executors.newFixedThreadPool(5); 固定线程个数
    //源码分析:                             
    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }   
    
    //Executors.newCachedThreadPool(); 缓存池,可扩展
    //源码分析:                             
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,//21亿 OOM:Out Of Memory,内存溢出
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }    
    
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    AI写代码

源码分析得出:(三个方法都有ThreadPoolExecutor)

继续点击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;
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    AI写代码

得到七大参数:

复制代码
    int corePoolSize,//核心线程池大小
    int maximumPoolSize,//最大核心线程池大小
    long keepAliveTime,//超时了没有人调用会释放
    TimeUnit unit, //超时单位
    BlockingQueue<Runnable> workQueue,//阻塞队列
    ThreadFactory threadFactory,//线程工厂: 创建线程的,一般不用动
    RejectedExecutionHandler handler//拒绝策略
    
    
    
    
      
      
      
      
      
      
      
      
      
    
    AI写代码

自定义线程池:

复制代码
    package pool;
    
    import java.util.concurrent.*;
    
    public class Demo2 {
    public static void main(String[] args) {
    
        // 自定义线程池!工作 ThreadPoolExecutor(七大参数)
        ExecutorService threadPool = new ThreadPoolExecutor(
          2,
          5,
          3,
          TimeUnit.SECONDS,
          new LinkedBlockingDeque<>(3),
          Executors.defaultThreadFactory(),
          //有四种拒绝策略,用适合于自己的!
          new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,尝试和最早的竞争,也不会抛出异常!
        );
    
        try {
            //最大承载: Deque + max
            //超过 RejectedExecutionException 抛出拒绝执行异常
            for (int i = 1; i <= 9; i++) {
                //使用了线程池之后,使用线程池来创建线程
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+" OK!");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //线程池用完,程序结束,关闭线程池
            threadPool.shutdown();
        }
    }
    }	
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    AI写代码

四种拒绝策略:

1、new ThreadPoolExecutor.AbortPolicy()

银行满了,还有人进来,就不处理这个人的,
抛出拒绝执行异常 RejectedExecutionException

运行结果:

在这里插入图片描述

2、new ThreadPoolExecutor.CallerRunsPolicy()

哪里来的去哪里!

运行结果:

在这里插入图片描述

3、new ThreadPoolExecutor.DiscardPolicy()

队列满了,丢掉任务,不会抛出异常

运行结果:

在这里插入图片描述

4、new ThreadPoolExecutor.DiscardOldestPolicy()

队列满了,尝试和最早的竞争,也不会抛出异常!

运行结果:

在这里插入图片描述

全部评论 (0)

还没有任何评论哟~