zoukankan      html  css  js  c++  java
  • 线程池(详解):三大方法、七大参数、四种拒绝策略

    线程池(重点)

    一:线程池:三大方法,七大参数,四种拒绝策略

      池化技术:
      01:程序的运行,本质 :占用系统的资源! 优化资源的使用! =>池化技术
      02:线程池、连接池、内存池、对象池///......创建、销毁。 十分浪费资源
      03:池化技术:事先准备好一些资源,有人要用,就来我这里拿,用完之后还给我。
      线程池的好处:
      01:降低资源的消耗
      02:提高响应的速度
      03:方便管理
      (重点)线程复用、可以控制最大并发数、管理线程
    二:三大方法:

      01:Executors.newSingleThreadExecutor()  //单个线程
        代码示例01
     1 package pool;
     2 
     3 import java.util.concurrent.ExecutorService;
     4 import java.util.concurrent.Executors;
     5 
     6 //Executors 工具类、3大方法
     7 
     8 public class Demo01 {
     9     public static void main(String[] args) {
    10 
    11         ExecutorService threadpool = Executors.newSingleThreadExecutor();     //单个线程
    12 
    13         try {
    14             for (int i = 0; i < 10; i++) {
    15                 //使用了线程池之后,使用线程池来创建线程
    16                 threadpool.execute(()->{
    17                     System.out.println(Thread.currentThread().getName()+" ok");
    18                 });
    19             }
    20         } catch (Exception e) {
    21             e.printStackTrace();
    22         } finally {
    23             //线程池用完,程序结束,关闭线程池
    24             threadpool.shutdown();   //(为确保关闭,将关闭方法放入到finally中)
    25         }
    26     }
    27 }

    运行结果: (10个任务被同一个线程所操作)

      

       02:newFixedThreadPool(int nThreads)     //创建一个固定的线程池的大小

        代码示例02

     1 package pool;
     2 
     3 import java.util.concurrent.ExecutorService;
     4 import java.util.concurrent.Executors;
     5 
     6 //Executors 工具类、3大方法
     7 
     8 public class Demo01 {
     9     public static void main(String[] args) {
    10 
    11         //最多5个线程同时执行,从控制台中查看结果
    12         ExecutorService threadpool = Executors.newFixedThreadPool(5);   //创建一个固定的线程池的大小,(5个线程)
    13 
    14         try {
    15             for (int i = 0; i < 10; i++) {
    16                 //使用了线程池之后,使用线程池来创建线程
    17                 threadpool.execute(()->{
    18                     System.out.println(Thread.currentThread().getName()+" ok");
    19                 });
    20             }
    21         } catch (Exception e) {
    22             e.printStackTrace();
    23         } finally {
    24             //线程池用完,程序结束,关闭线程池
    25             threadpool.shutdown();   //(为确保关闭,将关闭方法放入到finally中)
    26         }
    27     }
    28 }

    运行结果:(最高同时有5个线程在执行)

       03:newCachedThreadPool()      //缓存池,可伸缩的, 遇强则强,遇弱则弱

        代码示例03

     1 package pool;
     2 
     3 import java.util.concurrent.ExecutorService;
     4 import java.util.concurrent.Executors;
     5 
     6 //Executors 工具类、3大方法
     7 
     8 public class Demo01 {
     9     public static void main(String[] args) {
    10 
    11         ExecutorService threadpool = Executors.newCachedThreadPool();   //缓存池,可伸缩的, 遇强则强,遇弱则弱
    12 
    13         try {
    14             for (int i = 0; i < 10; i++) {
    15                 //使用了线程池之后,使用线程池来创建线程
    16                 threadpool.execute(()->{
    17                     System.out.println(Thread.currentThread().getName()+" ok");
    18                 });
    19             }
    20         } catch (Exception e) {
    21             e.printStackTrace();
    22         } finally {
    23             //线程池用完,程序结束,关闭线程池
    24             threadpool.shutdown();   //(为确保关闭,将关闭方法放入到finally中)
    25         }
    26     }
    27 }

    运行结果:(最高同时有10个线程在执行,可伸缩的, 遇强则强,遇弱则弱)

       三:七大参数

          01:三大方法之源码分析:

     1      (1)  newSingleThreadExecutor()              //单个线程
     2 
     3         public static ExecutorService newSingleThreadExecutor() {
     4                 return new FinalizableDelegatedExecutorService
     5                     (new ThreadPoolExecutor(1, 1,
     6                                             0L, TimeUnit.MILLISECONDS,
     7                                             new LinkedBlockingQueue<Runnable>()));
     8             }
     9         ==================================================================================
    10         (2)  newFixedThreadPool(int nThreads)       //创建一个固定的线程池的大小
    11 
    12         public static ExecutorService newFixedThreadPool(int nThreads) {
    13                 return new ThreadPoolExecutor(nThreads, nThreads,
    14                                               0L, TimeUnit.MILLISECONDS,
    15                                               new LinkedBlockingQueue<Runnable>());
    16             }
    17         ===================================================================================
    18         (3)  newCachedThreadPool()                  //缓存池,可伸缩的, 遇强则强,遇弱则弱
    19 
    20         public static ExecutorService newCachedThreadPool() {
    21                 return new ThreadPoolExecutor(0, Integer.MAX_VALUE,     //Integer.Max_VALUE  约等于21亿  //如果我们有这么多条线程一起跑的话,电脑会OOM(溢出),出现问题
    22                                               60L, TimeUnit.SECONDS,                          
    23                                               new SynchronousQueue<Runnable>());             
    24             }
    25         ====================================================================================
    26         (4) 三大方法所公共的  ThreadPoolExecutor() 方法
    27 
    28                                         ******7大参数******
    29 
    30         public ThreadPoolExecutor(int corePoolSize,                         //核心线程池大小
    31                                       int maximumPoolSize,                  //最大核心线程池大小
    32                                       long keepAliveTime,                   //超时了没有人调用就会释放
    33                                       TimeUnit unit,                        //超时单位
    34                                       BlockingQueue<Runnable> workQueue,    //阻塞队列
    35                                       ThreadFactory threadFactory,          //线程工厂,创建线程的,一般不用动
    36                                       RejectedExecutionHandler handler) {   //拒绝策略
    37                 if (corePoolSize < 0 ||
    38                     maximumPoolSize <= 0 ||
    39                     maximumPoolSize < corePoolSize ||
    40                     keepAliveTime < 0)
    41                     throw new IllegalArgumentException();
    42                 if (workQueue == null || threadFactory == null || handler == null)
    43                     throw new NullPointerException();
    44                 this.corePoolSize = corePoolSize;
    45                 this.maximumPoolSize = maximumPoolSize;
    46                 this.workQueue = workQueue;
    47                 this.keepAliveTime = unit.toNanos(keepAliveTime);
    48                 this.threadFactory = threadFactory;
    49                 this.handler = handler;
    50             }
      阿里巴巴开发手册中有如下规定:

       例如银行办理业务图:

      四:四种拒绝策略:


    /**

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

    五:手动(自定义)创建一个线程池:
     

     代码示例01    new ThreadPoolExecutor.AbortPolicy()  //银行满了,还有人进来,不处理这个人的,抛出异常
     1 package 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 Demo02 {
     9     public static void main(String[] args) {
    10         //自定义线程池! 工作中只会使用 ThreadPoolExecutor
    11         ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
    12                 2,                                  //核心线程池大小
    13                 5,                             //最大核心线程池大小
    14                 3,                                //超时了没有人调用就会释放
    15                 TimeUnit.SECONDS,                               //超时单位
    16                 new LinkedBlockingDeque<>(3),          //阻塞队列
    17                 Executors.defaultThreadFactory(),               //线程工厂,创建线程的,一般不用动
    18                 new ThreadPoolExecutor.AbortPolicy());  //银行满了,还有人进来,不处理这个人的,抛出异常
    19 
    20         try {
    21             //最大承载数,Deque + Max    (队列线程数+最大线程数)
    22             //超出 抛出 RejectedExecutionException 异常
    23             for (int i = 1; i <= 9; i++) {
    24                 //使用了线程池之后,使用线程池来创建线程
    25                 threadPool.execute(()->{
    26                     System.out.println(Thread.currentThread().getName()+" ok");
    27                 });
    28             }
    29         } catch (Exception e) {
    30             e.printStackTrace();
    31         } finally {
    32             //线程池用完,程序结束,关闭线程池
    33             threadPool.shutdown();      //(为确保关闭,将关闭方法放入到finally中)
    34         }
    35     }
    36 }

    运行结果(对比):

         

         

      代码示例02    new ThreadPoolExecutor.CallerRunsPolicy()    //哪来的去哪里

     1 package 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 Demo02 {
     9     public static void main(String[] args) {
    10         //自定义线程池! 工作中只会使用 ThreadPoolExecutor
    11         ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
    12                 2,                                  //核心线程池大小
    13                 5,                             //最大核心线程池大小
    14                 3,                                //超时了没有人调用就会释放
    15                 TimeUnit.SECONDS,                               //超时单位
    16                 new LinkedBlockingDeque<>(3),          //阻塞队列
    17                 Executors.defaultThreadFactory(),               //线程工厂,创建线程的,一般不用动
    18                 new ThreadPoolExecutor.CallerRunsPolicy());     //哪来的去哪里!
    19 
    20         try {
    21             //最大承载数,Deque + Max    (队列线程数+最大线程数)
    22             //超出 抛出 RejectedExecutionException 异常
    23             for (int i = 1; i <= 9; i++) {
    24                 //使用了线程池之后,使用线程池来创建线程
    25                 threadPool.execute(()->{
    26                     System.out.println(Thread.currentThread().getName()+" ok");
    27                 });
    28             }
    29         } catch (Exception e) {
    30             e.printStackTrace();
    31         } finally {
    32             //线程池用完,程序结束,关闭线程池
    33             threadPool.shutdown();      //(为确保关闭,将关闭方法放入到finally中)
    34         }
    35     }
    36 }

    运行结果:

       代码示例03    new ThreadPoolExecutor.DiscardPolicy() //队列满了,丢掉任务,不会抛出异常!

     1 package 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 Demo02 {
     9     public static void main(String[] args) {
    10         //自定义线程池! 工作中只会使用 ThreadPoolExecutor
    11         ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
    12                 2,                                  //核心线程池大小
    13                 5,                             //最大核心线程池大小
    14                 3,                                //超时了没有人调用就会释放
    15                 TimeUnit.SECONDS,                               //超时单位
    16                 new LinkedBlockingDeque<>(3),          //阻塞队列
    17                 Executors.defaultThreadFactory(),               //线程工厂,创建线程的,一般不用动
    18                 new ThreadPoolExecutor.DiscardPolicy());        //队列满了,丢掉任务,不会抛出异常!
    19 
    20         try {
    21             //最大承载数,Deque + Max    (队列线程数+最大线程数)
    22             //超出 抛出 RejectedExecutionException 异常
    23             for (int i = 1; i <= 9; i++) {
    24                 //使用了线程池之后,使用线程池来创建线程
    25                 threadPool.execute(()->{
    26                     System.out.println(Thread.currentThread().getName()+" ok");
    27                 });
    28             }
    29         } catch (Exception e) {
    30             e.printStackTrace();
    31         } finally {
    32             //线程池用完,程序结束,关闭线程池
    33             threadPool.shutdown();      //(为确保关闭,将关闭方法放入到finally中)
    34         }
    35     }
    36 }

    运行结果:

       04:代码示例    new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,尝试和最早的竞争,也不会抛出异常

     1 package 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 Demo02 {
     9     public static void main(String[] args) {
    10         //自定义线程池! 工作中只会使用 ThreadPoolExecutor
    11         ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
    12                 2,                                  //核心线程池大小
    13                 5,                             //最大核心线程池大小
    14                 3,                                //超时了没有人调用就会释放
    15                 TimeUnit.SECONDS,                               //超时单位
    16                 new LinkedBlockingDeque<>(3),          //阻塞队列
    17                 Executors.defaultThreadFactory(),               //线程工厂,创建线程的,一般不用动
    18                 new ThreadPoolExecutor.DiscardOldestPolicy());  //队列满了,尝试和最早的竞争,也不会抛出异常
    19 
    20         try {
    21             //最大承载数,Deque + Max    (队列线程数+最大线程数)
    22             //超出 抛出 RejectedExecutionException 异常
    23             for (int i = 1; i <= 9; i++) {
    24                 //使用了线程池之后,使用线程池来创建线程
    25                 threadPool.execute(()->{
    26                     System.out.println(Thread.currentThread().getName()+" ok");
    27                 });
    28             }
    29         } catch (Exception e) {
    30             e.printStackTrace();
    31         } finally {
    32             //线程池用完,程序结束,关闭线程池
    33             threadPool.shutdown();      //(为确保关闭,将关闭方法放入到finally中)
    34         }
    35     }
    36 }

    运行结果:

  • 相关阅读:
    Lc617_合并二叉树
    Lc257_二叉树的所有路径
    Lc222_完全二叉树的节点个数
    记github下载上传遇到的各种问题
    Lc101_对称二叉树
    Lc222_翻转二叉树
    二叉树的dfs 与 bfs (递归遍历)
    全球最火的程序员学习路线!没有之一!3天就在Github收获了接近1w点赞
    大二逃课总结的1.2w字的计算机网络知识!扫盲!
    「IDEA插件精选」安利一个IDEA骚操作:一键生成方法的序列图
  • 原文地址:https://www.cnblogs.com/liangbaolong/p/13193591.html
Copyright © 2011-2022 走看看