Java--JUC--ThreadPool(线程池)

  1. 例子:ThreadPoolDemo,避免new 连接
  2. 为什么要用线程池
    1.  
        
  3. 如何使用线程池
    1. Arrays.copyOf();  数组的工具类
      Collections.synchronizedList();  集合的工具类
       ExecutorService threadPool= Executors.newFixedThreadPool(5);
      //一池五个受理线程,类似于银行有五个受理窗口
    2. 架构说明
      1.  
          
    3. 编码实现
      1.  
        //        执行长期任务性能好,创建一个线程池,一池有n个固定的线程,有固定的线程数的线程池
                ExecutorService executorService=Executors.newFixedThreadPool(5);

         

      2.  

          
        //        一个一个任务的执行,一池一线程,类似于1个受理窗口
                ExecutorService executorService1=Executors.newSingleThreadExecutor();

         

      3. //          一池n线程,类似于银行有n个受理窗口,自动扩容
                ExecutorService executorService2=Executors.newCachedThreadPool();

         

    4. ThreadPool底层原理(ThreadPoolExecutor)
      1.  

         

               
  4. 线程池的几个重要的参数
    1.     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;
          }

       

    2. corePoolSize: 线程池中的常驻核心线程数

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

    4. keepAliveTime: 多余的空闲线程的存活时间
      当前池中线程数量超过corePoolSize时,当空闲时间
      达到keepAliveTime时,多余线程会被销毁直到
      只剩下corePoolSize'个线程为止

    5. unit: keepAliveTime的单位

    6. workQueue: 任务队列,被提交但尚未被执行的任务

    7. threadFactory: 表示生成线程池中工作线程的线程工厂,
      用于创建线程,- -般默认的即可

    8. handler: 拒绝策略,表示当队列满了,并且工作线程大于
      等于线程池的最大线程数(maximumPoolSize) 时如何来拒绝
      请求执行的runnable的策略

       
      
         
  5. 线程池底层工作原理(线程池只是控制运行的线程数量)
    1. corePoolSize=今日当值窗口 
    2. maximumPoolSize=扩容窗口(扩容的窗口包括今日当值窗口)
    3. blocking Queue=候客区
    4.  

       

       

  6. 线程池有哪个?生产中如何设置合理的参数
    1. 线程池的拒绝策略

      1. 是什么
        1.  
            
      2. JDK内置的拒绝策略

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

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

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

        4. DiscardPolicy:该策略默默地丢弃无法处理的任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的一-种策略。

              
      3. 以上内置拒绝策略均实现了RejectedExecutionHandle接口

    2. 在工作中单一的/固定数的/可变的三种创建线程池的方法哪个用的多?超级大坑

      1. 答案是一个都不用,我们在工作中只能使用自定义的

      2. Executor中JDK给你提供了,为什么不用
        1.  

          OOM : java内存溢出

        2. 空指针异常,类型转换异常 

            
    3. 在工作中如何使用线程池,是否自定义过线程池:

      1. 代码 
      2. package com.model.threadpool;
        
        import java.util.concurrent.*;
        
        /**
         * @Description:测试类
         * @Author: 张紫韩
         * @Crete 2021/6/8 17:12
         */
        public class ThreadPoolDemo {
            public static void main(String[] args) {
                System.out.println(Runtime.getRuntime().availableProcessors());  //内核cpu的数量
                ExecutorService threadPool =
                        new ThreadPoolExecutor(
                                2,  //线程核心数
                                5, //线程最大数  (最大的线程数量=内核数量+1)
                                3L,  //保留时间
                                TimeUnit.SECONDS,  //保留时间的单位
                                new LinkedBlockingQueue<>(3), //阻塞队列(候车区)
                                Executors.defaultThreadFactory(), //线程工程默认值
                                new ThreadPoolExecutor.AbortPolicy()); //1.拒绝策略,默认(抛出异常)
        //                        new ThreadPoolExecutor.CallerRunsPolicy()); //2.拒绝策略(会退给请求者)
        //                        new ThreadPoolExecutor.DiscardPolicy()); //3.拒绝策略(允许任务丢失,抛弃无法执行的任务)
        //                        new ThreadPoolExecutor.DiscardPolicy()); //4.拒绝策略(允许任务丢失,抛弃执行来的最晚的无法处理的任务)
        
                //最大的线程数容量是: 线程最大数+阻塞队列数
        
                /**
                 * 模拟十人来银行办理业务,目前池子中只有5名工作人员
                         * */
                try {
                    for (int i = 0; i < 9 ; i++) {
                        final int t=i;
                        threadPool.execute(()->{
                            System.out.println(Thread.currentThread().getName()+"处理业务\t"+t+"办理业务");
                        });
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    threadPool.shutdown();
        
                }
        
            }
        
        }

         


         

         

         
posted @ 2021-06-08 19:01  张紫韩  阅读(45)  评论(0编辑  收藏  举报