2022.8.21 线程池

11、线程池(重点)

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

池化技术

程序的运行,本质:占用系统的资源!优化资源的使用! ==> 引进了一种技术池化池

线程池、连接池、内存池、对象池…

池化技术:事先准备好一些资源,有人要用,就来我这里拿,用完之后还给我。

线程池的好处

1、降低资源的消耗

2、提高响应的速度

3、方便管理

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

三大方法

单个线程

 1  package com.xing.pool;
 2  3  import java.util.concurrent.ExecutorService;
 4  import java.util.concurrent.Executors;
 5  //Executors 工具类 三大方法
 6  public class Test01 {
 7      public static void main(String[] args) {
 8          //这个线程池只有一个线程处理
 9          ExecutorService threadpool = Executors.newSingleThreadExecutor();
10 11          try{
12              for(int i =1;i < 10; i++){
13                  //使用了线程池之后,使用线程池来创建线程
14                  threadpool.execute(()->{
15                      System.out.println(Thread.currentThread().getName() + "OK" );
16                  });
17              }
18          }catch (Exception e){
19              e.printStackTrace();
20          }finally {
21              //程序结束要停止线程池
22              threadpool.shutdown();
23          }
24 25      }
26  }
27

 

创建一个固定先线程池的大小

 1  package com.xing.pool;
 2  3  import java.util.concurrent.ExecutorService;
 4  import java.util.concurrent.Executors;
 5  //Executors 工具类 三大方法
 6  public class Test01 {
 7      public static void main(String[] args) {
 8          //创建一个固定的线程池的大小   最多5个线程并发
 9          ExecutorService threadpool = Executors.newFixedThreadPool(5);
10        
11 12          try{
13              for(int i =1;i < 10; i++){
14                  //使用了线程池之后,使用线程池来创建线程
15                  threadpool.execute(()->{
16                      System.out.println(Thread.currentThread().getName() + "==>OK" );
17                  });
18              }
19          }catch (Exception e){
20              e.printStackTrace();
21          }finally {
22              //程序结束要停止线程池
23              threadpool.shutdown();
24          }
25 26      }
27  }
28

 

 1  package com.xing.pool;
 2  3  import java.util.concurrent.ExecutorService;
 4  import java.util.concurrent.Executors;
 5  //Executors 工具类 三大方法
 6  public class Test01 {
 7      public static void main(String[] args) {
 8          //可伸缩的缓存
 9          ExecutorService threadpool = Executors.newCachedThreadPool();
10          try{
11              for(int i =1;i < 10; i++){
12                  //使用了线程池之后,使用线程池来创建线程
13                  threadpool.execute(()->{
14                      System.out.println(Thread.currentThread().getName() + "==>OK" );
15                  });
16              }
17          }catch (Exception e){
18              e.printStackTrace();
19          }finally {
20              //程序结束要停止线程池
21              threadpool.shutdown();
22          }
23 24      }
25  }
26

 

三大方法源码

 1  public static ExecutorService newSingleThreadExecutor() {
 2      return new FinalizableDelegatedExecutorService
 3          (new ThreadPoolExecutor(1, 1,
 4                                  0L, TimeUnit.MILLISECONDS,
 5                                  new LinkedBlockingQueue<Runnable>()));
 6  }
 7  8  public static ExecutorService newFixedThreadPool(int nThreads) {
 9      return new ThreadPoolExecutor(nThreads, nThreads,
10                                    0L, TimeUnit.MILLISECONDS,
11                                    new LinkedBlockingQueue<Runnable>());
12  }
13  public static ExecutorService newCachedThreadPool() {
14      return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
15                                    60L, TimeUnit.SECONDS,
16                                    new SynchronousQueue<Runnable>());
17  }

 

这里看出都new了一个ThreadPoolExecutor的类,点击进去看他的源码

 1  //有7个参数  7大参数
 2  public ThreadPoolExecutor(int corePoolSize,//核心线程池大小
 3                            //核心线程池不够时 “增加线程池大小”
 4                            int maximumPoolSize,//最大的线程池大小 
 5                            long keepAliveTime,//“增加的线程池”存活的时间,超时无人调用就会释放
 6                            TimeUnit unit,//超时的单位
 7                            BlockingQueue<Runnable> workQueue,//阻塞队列
 8                            ThreadFactory threadFactory,//创建线程的工厂,一般不用动
 9                            RejectedExecutionHandler handler) {//拒绝策略
10      if (corePoolSize < 0 ||
11          maximumPoolSize <= 0 ||
12          maximumPoolSize < corePoolSize ||
13          keepAliveTime < 0)
14          throw new IllegalArgumentException();
15      if (workQueue == null || threadFactory == null || handler == null)
16          throw new NullPointerException();
17      this.acc = System.getSecurityManager() == null ?
18          null :
19      AccessController.getContext();
20      this.corePoolSize = corePoolSize;
21      this.maximumPoolSize = maximumPoolSize;
22      this.workQueue = workQueue;
23      this.keepAliveTime = unit.toNanos(keepAliveTime);
24      this.threadFactory = threadFactory;
25      this.handler = handler;
26  }

 

七大参数

4种拒绝策略

 1  package com.xing.pool;
 2  3  import java.util.concurrent.*;
 4  5  public class Test01 {
 6      public static void main(String[] args) {
 7  8          //自定义线程池
 9          ExecutorService threadpool = new ThreadPoolExecutor(2,  //默认处理口数,目前银行开放的窗口数
10                  5, //最大处理口数,人数太多了  将开放的窗口数增加到5个
11                  3,//超出空闲时间除了默认线程数其他都释放  超过3秒钟额外开放的5-2=3个窗口没人用就会关闭
12                  TimeUnit.SECONDS,//时间单位
13                  new LinkedBlockingDeque<>(3),//提供等待区的队列  候客区最多3个人
14                  Executors.defaultThreadFactory(),//一般不会变,默认线程模式
15                  new ThreadPoolExecutor.AbortPolicy()//拒绝策略,开放到5个窗口也不够用的话,多余的人执行的策略
16                  // new ThreadPoolExecutor.AbortPolicy());//拒绝策列的一种,服务口和等待队列都满了的时候,还有人进来,抛出异常
17                  // new ThreadPoolExecutor.CallerRunsPolicy());//哪来的回哪去(main处理) 比如你爸爸 让你去通知妈妈洗衣服,妈妈拒绝,让你回去通知爸爸洗
18                  // new ThreadPoolExecutor.DiscardPolicy());//拒绝策列的一种,会丢掉多余的任务,不会抛出异常
19                  // new ThreadPoolExecutor.DiscardOldestPolicy());//拒绝策列的一种,服务口和等待队列都满了的时候,后面进来的人会尝试去和第一个竞争,不会抛出异常
20                  );
21          try{
22              //最大承载线程数:LinkedBlockingDeque + 最大处理口数  3+5=8  同时处理8个线程时,到达最大处理口数
23              // RejectedExecutionException  超出最大承载异常
24              /*
25              * 同时处理5个人   2个人去窗口,3个人候客厅,开启窗口数达到3
26              *        6       2          3                       3,最大线程被触发
27              *        7       2          3                       4,最大线程被触发
28              *        8       2          3                       5,最大线程被触发,达到最大承载线程数
29              *        9       2          3                       5,最大线程被触发,达到最大承载线程数,根据拒绝策略处理此线程
30              *
31              */
32              for(int i =1;i < 10; i++){
33                  //使用了线程池之后,使用线程池来创建线程
34                  threadpool.execute(()->{
35                      System.out.println(Thread.currentThread().getName() + "==>OK" );
36                  });
37              }
38          }catch (Exception e){
39              e.printStackTrace();
40          }finally {
41              //程序结束要停止线程池
42              threadpool.shutdown();
43          }
44 45      }
46  }
47

 

最大线程数如何定义

  • cpu 密集型 ,几核,就是几,可以保持cpu的效率最高

  • IO 密集型 > 判断你的程序中十分消耗IO的线程 一般设置为2倍

    • 假如程序有15个大型任务,io十分占用资源 设置为30

 1  package com.xing.pool;
 2  3  import java.util.concurrent.Executors;
 4  import java.util.concurrent.LinkedBlockingDeque;
 5  import java.util.concurrent.ThreadPoolExecutor;
 6  import java.util.concurrent.TimeUnit;
 7  8  public class Test02 {
 9      public static void main(String[] args) {
10          最大线程数如何定义
11 12          
13          //自定义线程池
14          System.out.println(Runtime.getRuntime().availableProcessors());//获取cpu的核数
15          ThreadPoolExecutor executorService = new ThreadPoolExecutor(
16                  2,//默认处理口数
17                  Runtime.getRuntime().availableProcessors(),//最大处理口数  cpu核数
18                  3,//超出空闲时间除了默认线程数其他都释放
19                  TimeUnit.SECONDS,//时间单位
20                  new LinkedBlockingDeque<>(3),//提供等待区的队列
21                  Executors.defaultThreadFactory(),//一般不会变,默认线程模式
22                  new ThreadPoolExecutor.AbortPolicy());//拒绝策列的一种,服务口和等待队列都满了的时候,还有人进来,抛出异常
23          try {
24              for (int i = 0; i < 9; i++) {
25                  executorService.execute(()->{
26                      System.out.println(Thread.currentThread().getName() + "ok");
27                  });
28              }
29          } catch (Exception e) {
30              e.printStackTrace();
31          }finally {
32              executorService.shutdown();
33          }
34      }
35  }

 

posted @ 2022-08-21 21:41  暴躁C语言  阅读(7)  评论(0编辑  收藏  举报