• java 线程池


    执行流程

      1, 创建线程池后, 默认不会创建线程, 等到有任务带来才创建线程, 即一个线程处理一个任务
      2, 当线程数量达到核心线程数时, 任务放进队列, 如果放入队列失败, 创建新线程处理任务(此时线程池线程数大于核心线程数)
      3, 如果线程数大于最大线程数, 执行拒绝策略处理任务

    构造方法

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
                BlockingQueue<Runnable> workQueue);
     
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
                BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory);
     
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
                BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler);
     
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);

    参数解释

      corePoolSize: 核心线程数, 当线程数量达到 corePoolSize 后, 后面的任务将会被放进队列排队

      maximumPoolSize: 能创建的最大线程数

      keepAliveTime: 当线程数量大于核心线程数量的时候生效, 表示空闲时间, 一旦超过这个时间, 该线程将被销毁

      unit: 超时单位, TimeUtil 规定, 有7中静态成员变量

      workQueue: 一个阻塞队列, 保存等待执行的任务

        ArrayBlockingQueue: 基于数组实现的先进先出队列, 创建时必须指定大小, 当需要处理的任务大于队列的大小时, 拒绝策略生效
        LinkedBlockingQueue: 基于链表的先进先出队列, 创建时可选指定大小, 如果不指定默认是 Integer.MAX_VALUE
        synchronousQueue: 不保存任务, 直接新建一个线程来执行新来的任务

      threadFactory: 线程工场, 用于创建线程

      handler: 拒绝策略

        ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常, 这是默认的方式
        ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
        ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
        ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

    常用方法

      public static ExecutorService newFixedThreadPool(int nThreads): 创建线程池, 参数表示核心线程数, 核心线程数等于最大线程数, 使用 LinkedBlockingQueue 队列

      public static ExecutorService newSingleThreadExecutor(): 创建线程池, 核心线程数和最大线程数为 1 使用 LinkedBlockingQueue 队列

      public static ExecutorService newCachedThreadPool(): 创建线程池, 核心线程数为 0, 最大线程数为 Integer.MAX_VALUE 使用 SynchronousQueue 队列

      execute(): 向线程池提交任务
      submit(): 也是向线程池提交任务, 能获取到线程的返回值
      shutdown(): 关闭线程池, 停止接收新任务, 等待处理完已经接收的任务后关闭
      shutdownNow(): 关闭线程池, 立即关闭, 打断正在处理的任务, 清空队列, 返回未处理的任务
      getQueue().size(): 队列中等待的任务数量
      getPoolSize(): 线程数量
      getCompletedTaskCount(): 已经处理的任务数量

    使用 new ThreadPoolExecutor() 创建线程池

    class MyThread implements Runnable{
        private int index;
    
        public MyThread(int index){
            this.index = index;
        }
    
        @Override
        public void run() {
            System.out.println("处理任务:" + index);
        }
    }
    public class Test1 {
        public static void main(String[] args){
            
            // 任务队列
            ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(5);
            // 拒绝策略
            ThreadPoolExecutor.DiscardPolicy handler = new ThreadPoolExecutor.DiscardPolicy();
    
            // 创建线程池
            ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 3, 100, TimeUnit.MICROSECONDS, queue, handler);
    
            // 1. 任打印 1-15, 每次打印就是一个任务, 有 15 个任务
            // 2. 15 个任务, 每次只能处理 2 个, 因为 corePoolSize 是 2; 所以将会有任务进行排队
            for (int i = 0; i < 15; i++){
                MyThread myThread = new MyThread(i);
                // 1. 每个队列只能放 5 个任务, 因为队列指定的数量是 5; 所以会有任务放入不成功, 将会创建新线程
                // 2. 最大线程数是 3, 因为 maximumPoolSize 是 3; 所以会有任务将被拒绝
                // 3. 这里使用的拒绝策略是: 直接抛弃, 并且不抛出异常
                executor.execute(myThread);
            }
            // 关闭服务
            executor.shutdown();
    
        }
    }
  • 相关阅读:
    springboot2系列目录
    zookeeper 集群部署
    canal 配置 详细说明
    在Docker环境下部署Kafka
    Spring4新特性
    centos7 卸载 jdk
    Kafka安装
    Scala 面向对象(三):package 包 (二)
    Scala 基础(七):Scala 运算符
    Maven 专题(四):什么是Maven
  • 原文地址:https://www.cnblogs.com/huanggy/p/9865494.html
Copyright © 2020-2023  润新知