首页 > 编程语言 > 详细

线程池

时间:2021-05-04 17:46:46      阅读:31      评论:0      收藏:0      [点我收藏+]

线程池

  • 线程池:三大方法、7大参数、4种拒绝策略

  • 池化技术

    程序的运行,本质:占用系统的资源! 优化资源的使用!=>池化技术
    线程池、连接池、内存池、对象池///….. 创建、销毁。十分浪费资源
    池化技术:事先准备好一些资源,有人要用,就来我这里拿,用完之后还给我。

  • 线程池的好处:

    1、降低资源的消耗
    2、提高响应的速度
    3、方便管理。

  • 线程复用、可以控制最大并发数、管理线程

线程池:三大方法

  • 技术分享图片

  • // Executors  工具类,三大方法
    // 使用线程池来创建线程,不用 new Thread
    public class Test01 {
        public static void main(String[] args) throws InterruptedException {
            // ExecutorService executorService = Executors.newSingleThreadExecutor();//单个线程
            // ExecutorService executorService = Executors.newFixedThreadPool(5);     // 创建一 个固定的线程池的大小
            ExecutorService executorService = Executors.newCachedThreadPool();     // 可伸缩 的,遇强则强,遇弱则弱
            try {
                for (int i = 0; i < 8; i++) {
                    //使用了线程池之后,使用线程池来创建线程
                    executorService.execute(() -> {
                        System.out.println(Thread.currentThread().getName());
                    });
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //程序结束要关闭线程池
                executorService.shutdown();
            }
        }
    }
    
  • 七大参数

    • 源码分析

      newSingleThreadExecutor

      public static ExecutorService newSingleThreadExecutor() {
          return new FinalizableDelegatedExecutorService
              (new ThreadPoolExecutor(1, 1,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>()));
      }
      

      newFixedThreadPool

      public static ExecutorService newFixedThreadPool(int nThreads) {
          return new ThreadPoolExecutor(nThreads, nThreads,
                                        0L, TimeUnit.MILLISECONDS,
                                        new LinkedBlockingQueue<Runnable>());
      }
      

      newCachedThreadPool

      public static ExecutorService newCachedThreadPool() {
          return new ThreadPoolExecutor(0, Integer.MAX_VALUE, //21亿
                                        60L, TimeUnit.SECONDS,
                                        new SynchronousQueue<Runnable>());
      }
      

      本质调用的是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.corePoolSize = corePoolSize;
              this.maximumPoolSize = maximumPoolSize;
              this.workQueue = workQueue;
              this.keepAliveTime = unit.toNanos(keepAliveTime);
              this.threadFactory = threadFactory;
              this.handler = handler;
          }
      

      技术分享图片

      • 手动创建一个线程池

      技术分享图片

      - 默认拒绝策略

      // 默认拒绝策略
      public class Test01 {
          public static void main(String[] args) throws InterruptedException {
              //以银行办理业务举例
              ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                      2,     //核心线程池大小:   在上班的业务员
                      5,//最大核心线程池大小: 最多5个窗口
                      3,  //超时时间,没有人调用就会释放
                      TimeUnit.SECONDS,//超时单位
                      new LinkedBlockingQueue<>(3),
                      Executors.defaultThreadFactory(),   //线程工厂,创建线程的
                      new ThreadPoolExecutor.AbortPolicy()    //默认的拒绝策略: 银行满了,有人进来,不处理这个人的业务,抛出异常
              );
              // java.util.concurrent.RejectedExecutionException 拒绝策略异常
              try {
                  for (int i = 0; i < 8; i++) {
                      //线程最大承载 队列+max的值  也就是 2+5,i如果等于8时,超出最大值,就会抛出异常
                      threadPoolExecutor.execute(() -> {//使用了线程池之后,使用线程池来创建线程
                          System.out.println(Thread.currentThread().getName());
                      });
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              } finally {
                  // 线程池用完,程序结束,关闭线程池
                  threadPoolExecutor.shutdown();
              }
          }
      }
      
      • 线程池满了就会回到主方法

      public class Test01 {
          public static void main(String[] args) throws InterruptedException {
              //以银行办理业务举例
              ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                      2,  //核心线程池大小:   在上班的业务员
                      5,  //最大核心线程池大小: 最多5个窗口
                      3,  //超时时间,没有人调用就会释放
                      TimeUnit.SECONDS,//超时单位
                      new LinkedBlockingQueue<>(3),
                      Executors.defaultThreadFactory(),   //线程工厂,创建线程的
                      new ThreadPoolExecutor.CallerRunsPolicy()   //哪来的去哪里,也就是超出最大承载的让主线程去处理
              );
              // java.util.concurrent.RejectedExecutionException 拒绝策略异常
              try {
                  for (int i = 0; i < 9; i++) {
                      //线程最大承载 队列+max的值  也就是 2+5,i如果等于9时
                      threadPoolExecutor.execute(() -> {//使用了线程池之后,使用线程池来创建线程
                          System.out.println(Thread.currentThread().getName());
                      });
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              } finally {
                  // 线程池用完,程序结束,关闭线程池
                  threadPoolExecutor.shutdown();
              }
          }
      }
      //pool-1-thread-1
      pool-1-thread-4
      main
      pool-1-thread-3
      pool-1-thread-2
      pool-1-thread-3
      pool-1-thread-4
      pool-1-thread-1
      pool-1-thread-5
      
      • 队列满了 不会抛出异常

      ublic class Test01 {
          public static void main(String[] args) throws InterruptedException {
              //以银行办理业务举例
              ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                      2,     //核心线程池大小:   在上班的业务员
                      5,//最大核心线程池大小: 最多5个窗口
                      3,  //超时时间,没有人调用就会释放
                      TimeUnit.SECONDS,//超时单位
                      new LinkedBlockingQueue<>(3),
                      Executors.defaultThreadFactory(),   //线程工厂,创建线程的
                      new ThreadPoolExecutor.DiscardPolicy()  //队列满了不会抛出异常,丢掉任务
              );
              // java.util.concurrent.RejectedExecutionException 拒绝策略异常
              try {
                  for (int i = 0; i < 9; i++) {
                      //线程最大承载 队列+max的值  也就是 2+5,i如果等于8时,超出最大值,就会抛出异常
                      threadPoolExecutor.execute(() -> {//使用了线程池之后,使用线程池来创建线程
                          System.out.println(Thread.currentThread().getName());
                      });
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              } finally {
                  // 线程池用完,程序结束,关闭线程池
                  threadPoolExecutor.shutdown();
              }
          }
      }
      //pool-1-thread-2
      pool-1-thread-4
      pool-1-thread-3
      pool-1-thread-1
      pool-1-thread-3
      pool-1-thread-2
      pool-1-thread-4
      pool-1-thread-5
      
      • DiscardOldestPolicy

      public class Test01 {
          public static void main(String[] args) throws InterruptedException {
              //以银行办理业务举例
              ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                      2,     //核心线程池大小:   在上班的业务员
                      5,//最大核心线程池大小: 最多5个窗口
                      3,  //超时时间,没有人调用就会释放
                      TimeUnit.SECONDS,//超时单位
                      new LinkedBlockingQueue<>(3),
                      Executors.defaultThreadFactory(),   //线程工厂,创建线程的
                      new ThreadPoolExecutor.DiscardOldestPolicy()    // 队列满了,尝试去和早的竞争,也不会 抛出异常!
              );
              // java.util.concurrent.RejectedExecutionException 拒绝策略异常
              try {
                  for (int i = 0; i < 9; i++) {
                      //线程最大承载 队列+max的值  也就是 2+5,i如果等于8时,超出最大值,就会抛出异常
                      threadPoolExecutor.execute(() -> {//使用了线程池之后,使用线程池来创建线程
                          System.out.println(Thread.currentThread().getName());
                      });
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              } finally {
                  // 线程池用完,程序结束,关闭线程池
                  threadPoolExecutor.shutdown();
              }
          }
      }
      
      //pool-1-thread-1
      pool-1-thread-3
      pool-1-thread-1
      pool-1-thread-1
      pool-1-thread-4
      pool-1-thread-2
      pool-1-thread-3
      pool-1-thread-3
      pool-1-thread-5
      
  • 四种拒绝策略

    /** new ThreadPoolExecutor.AbortPolicy() 			// 银行满了,还有人进来,不处理这个人的,抛出异 常
     *  new ThreadPoolExecutor.CallerRunsPolicy() 		// 哪来的去哪里!
     *  new ThreadPoolExecutor.DiscardPolicy() 			//队列满了,丢掉任务,不会抛出异常! 
     *  new ThreadPoolExecutor.DiscardOldestPolicy() 	//队列满了,尝试去和早的竞争,也不会 抛出异常! 
     * */
    

IO密集型和CPU密集型

  • 最大线程池该如何定义:调优

    CPU密集型: 几核CPU,就设置几,可以保持CPU的最高效率

    • 通过代码获取CPU的核数

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

    IO密集型:判断程序中十分耗IO的线程,设置线程数大于这个数就可以。

线程池

原文:https://www.cnblogs.com/saxonsong/p/14729416.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!