zoukankan      html  css  js  c++  java
  • 并发编程-15 ThreadPoolExecutor线程池

    线程池ExecutorService

    image-20210728141340541

    线程池状态

    ThreadPoolExecutor使用int的高3位来表示线程池状态,低29位表示线程数量

    状态 value 说明
    RUNNING(当线程池创建出来的初始状态) 111 能接受任务,能执行阻塞任务
    SHUTDOWN(调用shutdown方法) 000 不接受新任务,能执行阻塞任务 肯定可以 執行正在執行的任務
    STOP(调用shutDownNow) 001 不接受新任务,打断正在执行的任务,丢弃阻塞任务
    TIDYING(中间状态) 010 任务全部执行完,活动线程也没了
    TERMINATED(终结状态) 011 线程池终结

    构造方法(参数最多)

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

    1、核心线程数

    2、最大线程数(应急线程数||空闲线程)

    3、针对空闲线程的存活时间 如果超时了则把空闲的线程kill

    4、针对3的时间单位

    5、任务存放的队列

    6、线程工厂,主要是产生线程---作用主要是给线程起个自定义名字

    7、拒绝策略

    工作方式

    线程池中刚开始没有线程,当一个任务提交给线程池后,线程池会创建一个新线程来执行任务

    当线程数达到 核心线程数上限,这时再加入任务,新加的任务就会被加入队列当中去

    前提是有界队列,任务超过了队列大小时,会创建maximumPoolSize - corePoolSize数目的线程数目作为空显线程来执行任务

    如果线程达到maximumPoolSize 仍然有新任务这时会执行拒绝策略

    工厂方法

    newFixedThreadPool

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

    核心线程数==最大线程数(没有救急线程被创建),因此也无需超时时间

    阻塞队列是无界的,可以放任意数量的任务

    使用于任务量已知,相对耗时的任务

    newCachedThreadPool

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

    核心线程数是0,最大线程数是Integer.MAX_VALUE,全部都是空闲线程,60s后回收

    一个可根据需要创建新线程的线程池,如果现有线程没有可用的,则创建一个新线程并添加到池中,如果有被使用完但是还没销毁的线程,就复用该线程。终止并从缓存中移除那些已有60秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。

    这种线程池比较灵活,对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。

    newSingleThreadExecutor

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

    希望多个任务排队执行,线程数固定为1,任务书多于1时,会放入无界队列排队,任务执行完毕后,这唯一的线程也不会被释放。

    区别于自己创建一个单线程串行执行任务,如果任务执行失败而终止那么没有任何补救措施,而线程池还会创建一个线程,保证池的正常任务。

    Executors.newSingleThreadExecutor()线程个数始终为1,且不能修改,

    Executors.newFixedThreadPool(1) 初始时为1,以后还可以修改,对外暴露的是ThreadPoolExecutor对象,可以强转后调用setCorePoolSize等方法进行修改;

    提交任务

    提交一个任务

    void execute(Runnable command);

    提交一个任务 <有返回值>

    Future<?> submit(Runnable task);

    提交所有的任务

    List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;

    提交 tasks 中所有任务,哪个任务先成功执行完毕,返回此任务执行结果,其它任务取消

    T invokeAny(Collection<? extends Callable<T>> tasks) throws
    InterruptedException, ExecutionException;

    shutdown相关

    线程池状态变为SHUTDOWN
    不会接收新任务
    但已提交任务会执行完
    不会阻塞调用线程的执行

    void shutdown();

    线程池状态变为 STOP
    不会接收新任务
    会将队列中的任务返回
    并用 interrupt 的方式中断正在执行的任务

    List<Runnable> shutdownNow();

    调用 shutdown后,调用线程并不会等待所有任务运行结束,可以利用此方法等待

    boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
  • 相关阅读:
    Mosquitto搭建Android推送服务(一)MQTT简介
    Quartz定时任务简单实例
    Oracle基础知识(一)、简介与安装
    [2013-08-01]window.open
    C#中DataTable与泛型集合互转(支持泛型集合中对象包含枚举)
    C#代码安装Windows服务(控制台应用集成Windows服务)
    Node+Socket实现聊天室
    web前端架构
    Laravel-admin form 表单是增加或者修改
    Laravel-admin 消息提醒、播放音频、点击跳转
  • 原文地址:https://www.cnblogs.com/doagain/p/15072955.html
Copyright © 2011-2022 走看看