Java线程池基本原理

1.Executors类和ExecutorService接口

在这里插入图片描述

1.1 Executors工具类的使用

Executors类似于Collections作用域集合领域一样,它是线程池的工具类,可以通过静态方法构造出不同特性的线程池让我们快速使用。常见的Executors创建线程池有几种:

        - `ExecutorService executorService = Executors._newFixedThreadPool_(10);`这是创建定长的线程池,核心线程和最大线程数一致,且是一个无界队列(理论上)LinkedBlockingQueue实现。
        - `ExecutorService executorService = Executors._newCachedThreadPool_();`这是创建可缓存线程池,他核心线程为0,最大线程是Integer.MAX_VALUE,队列使用的`SynchronousQueue`,所以这种线程池在面对多任务的时候会有许多线程创建。
        - `ExecutorService executorService = Executors._newSingleThreadExecutor_();`这是创建一个单线程的线程池,他的核心和最大线程数量只有1个,使用无界队列LinkedBlockingQueue。
        - `ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();`这是创建一个周期任务线程池,他的核心线程数只有1个,基于ScheduledExecutorService接口的实现。

1.2 ExecutorService接口

ExecutorService接口继承自Executor接口,Executor接口至定义了一个execute(Runnable r)抽象方法,ExecutorService是对Executor的补充,它定义了线程池的一系列同样方法:

        - void shutdown():线程有序关闭,不会接受新的任务,等待现有任务执行结束再关闭。
        - List<Runnable> shutdownNow():强制关闭线程池,返回`正在等待中的任务列表`。
        - boolean isShutdown():判断线程池是否关闭。
        - Future submit(Callable):提交Callable任务。
        - Future submit(Runnable r, T result):支持提交Runnable类型的有返回值的任务。
        - List<Future> invokeAll(Collection<? extends Callable> tasks):提交一组Callable任务。

1.3 自定义线程池ThreadPoolExecutor

ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 
                                                       10, 
                                                       60L, 
                                                       TimeUnit.SECONDS, 
                                                       new ArrayBlockingQueue<>(50),
                                                       new ThreadFactory(){
                                                            @Override
                                                            public Thread newThread(Runnable r) {return null;}},
                                                       new RejectedExecutionHandler(){
                                                            @Override
                                                            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {}}
                                                       );

threadPool.execute(() -> {xxx});
Future<?> result = threadPool.submit(() -> {xxx});

2.线程池参数含义

  - int corePoolSize:核心线程的数量,在未设置核心线程的超时时间,他们是常驻的。
  - int maximumPoolSize:最大线程的数量。
  - long keepAliveTime:当线程数大于核心线程时,多余的空闲线程的最大存活时间。
  - TimeUnit unit:存活时间的单位。
  - BlockingQueue<Runnable> workQueue:任务等待队列。
  - ThreadFactory threadFactory:线程工厂,需要具体实现。
  - RejectedExecutionHandler handler:当工作队列满时,后续的任务提交的拒绝策略,需要具体实现。常见的实现有:拒绝任务并抛异常、拒绝任务不抛异常、交由调用者线程执行、丢弃最旧的任务。也可以自己实现。

3.线程池的工作流程

在这里插入图片描述

线程池ThreadPoolExecutor的工作流程:

     1. 最开始线程池里没有工作线程,当有一个任务提交进来后,线程池就会为其addWord创建一个线程来执行这个任务。
     1. 当任务继续提交,如果总的线程数已经达到了核心线程数的阈值,那么新的任务就会进入阻塞队列中去。不过这里的任务不会立即入队,而是会再次check检查线程池的状态。
     1. 如果没有任务继续提交或者队列是无界队列,那么线程池的线程数量不会继续增加,核心工作线程不断消费队列的任务。
     1. 如果仍然有任务提交,一旦任务阻塞队列满了,那么线程池就会创建maxThreads - coreThreads数量线程来消费队列中的任务。
     1. 这些非核心线程的线程在执行完任务后,没有任务可执行后经过一段时间就会被回收。
     1. 如果队列已满的情况,且线程池线程的数量已经超过最大的阈值,新的任务就会触发拒绝策略。

4.线程池原理窥探

4.1 线程池的状态如何记录

线程池的运行状态是通过他的成员变量COUNT_BITS,来记录。他是表示int的位数。count_bits = 32-3 = 29。线程池用int的高3位来表示线程池的运行状态,后29位表示线程数量。

线程池状态3位二进制的状态值说明
running111能够接收任务,能够阻塞任务
shutdown(调用shutdown方法)000不接受新任务,执行正在执行的任务
stop(调用shutDownNow方法)001不接受新任务,打断正在执行的任务,丢弃队列中的任务。
tidying010任务全部执行完毕,活动线程回收
terminated011线程池终结状态

在这里插入图片描述

4.2 线程池的任务提交流程

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Minor王智

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值