java--线程池(3大方法、7大参数、四种拒绝策略)

什么是线程池?
线程池:一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。

线程池的好处:
1.降低资源消耗
2.提高响应速度
3.方便管理

线程池: 三大方法
创建线程池的三大方法如下:

  ExecutorService service = Executors.newSingleThreadExecutor();//单个线程
  /*public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue()));
    }*/
  ExecutorService service = Executors.newFixedThreadPool(5);//创建一个固定的线程池的大小
  /* public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue());
    }*/
  ExecutorService service = Executors.newCachedThreadPool();//缓存线程池,可伸缩的
  /*public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue());
    }*/

但是在阿里巴巴开发手册中提到:
java--线程池(3大方法、7大参数、四种拒绝策略)_第1张图片

在上面三大方法中,本质所有线程池最终都调用的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;
    }

七大参数举例说明:
java--线程池(3大方法、7大参数、四种拒绝策略)_第2张图片
核心线程大小表示上述图中银行一般情况下开设的窗口(线程数),阻塞队列相当于银行的侯客区,当线程数大于侯客厅+核心线程数的数量时,线程数继续增大时,线程池数的使用依次增加,直至达到最大线程池的大小,达到最大处理线程数还增加的话就会使用拒绝策略!(最大处理线程数=最大线程数+阻塞队列大小)(说的不是很明白,不理解建议可以看一下狂神的juc 链接:https://www.bilibili.com/video/BV1B7411L7tE?p=22)

自定义创建线程池:

ExecutorService threadPool =
 new ThreadPoolExecutor(3, //核心线程池大小
                        5, //最大并发数
                        10, //超时时间
                        TimeUnit.SECONDS, //时间单位
                        new LinkedBlockingQueue<>(),//线程等候队列
                        Executors.defaultThreadFactory(), //线程创建工厂
                        new ThreadPoolExecutor.DiscardOldestPolicy());//拒绝策略

最大线程到底应该如何定义?
1、CPU密集型 几核,就是几,可以保证CPU的效率最高
java获取cpu核数的方法:

 Runtime.getRuntime().availableProcessors()

2、IO 密集型 判断程序中十分耗I/O的线程, 大于两倍

四种默认的拒绝策略
在这里插入图片描述

/**
 * new ThreadPoolExecutor.AbortPolicy() 超出最大处理线程抛出异常(最大处理线程数=最大线程数+阻塞队列大小)
 * new ThreadPoolExecutor.CallerRunsPolicy() 从哪个线程创建就由那个线程执行(如main线程创建,就在main线程执行)
 * new ThreadPoolExecutor.DiscardPolicy() 队列满了不会抛出异常
 * new ThreadPoolExecutor.DiscardOldestPolicy() 尝试去和第一个竞争,也不会抛出异常
 */

这是我通过B站狂神说Java学习线程池所做的笔记,对你有帮助的话或者有疑问的话欢迎点赞评论收藏!谢谢大家!

你可能感兴趣的:(JUC,java,多线程,并发编程)