线程池的介绍与使用

什么是线程池

线程池:提供了一个线程队列。队列中保存了所有等待状态的线程,避免了创建与销毁的额外开销,提高了响应速度

线程池的体系结构

在这里插入图片描述

线程池的优势

线程的复用、控制线程的并发数、管理线程

线程池工具类 Executors(三大方法)

  • newFixedThreadPool:创建一个固定线程的线程池
  • newSingleThreadExecutor:创建单个线程池,线程池中只有一个线程
  • newCachedThreadPool:缓存线程池,线程数量不固定,可以根据需求自动更改数量
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>(),
                                    threadFactory));
    }

七大参数

public ThreadPoolExecutor(int corePoolSize,//核心线程池大小
                              int maximumPoolSize,//最大核心线程池大小
                              long keepAliveTime,//空闲线程的保持活跃时间,超时就会释放该线程
                              TimeUnit unit,//时间单位
                              BlockingQueue<Runnable> workQueue,//阻塞队列
                              ThreadFactory threadFactory,//创建线程的工厂,一般不用动
                              RejectedExecutionHandler handler) {//拒绝策略
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }
  • newScheduledThreadPool:创建一个固定大小的线程池,可以延迟或定期执行的执行任务,类似Timer。

四种拒绝策略

什么时候触发拒绝策略呢?
当线程池的使用量已经达到了整个池子最大线程数(最大核心线程数 + 阻塞队列),此时还有线程进来,就会触发拒绝策略
在这里插入图片描述

  • AbortPolicy:不处理,直接抛异常
  • DiscardOldestPolicy:尝试去和最早的竞争,不会抛出异常
  • CallerRunsPolicy:从哪个线程来的就回哪个线程去,让原来的线程处理
  • DiscardPolicy:直接丢掉任务,不会抛出异常

池的最大大小该怎么设置?
CPU密集型:定义为电脑的处理器个数,可以保持CPU的效率最高
IO密集型:判断特别消耗io的线程的个数,定位为它的两倍

线程池的状态

在类ThreadPoolExecutor中可以看到线程池的状态
线程池的5种状态:RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED。

状态解释

	 /*   RUNNING:  Accept new tasks and process queued tasks
     *   SHUTDOWN: Don't accept new tasks, but process queued tasks
     *   STOP:     Don't accept new tasks, don't process queued tasks,
     *             and interrupt in-progress tasks
     *   TIDYING:  All tasks have terminated, workerCount is zero,
     *             the thread transitioning to state TIDYING
     *             will run the terminated() hook method
     *   TERMINATED: terminated() has completed
 // runState is stored in the high-order bits
    private static final int RUNNING    = -1 << COUNT_BITS;
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    private static final int STOP       =  1 << COUNT_BITS;
    private static final int TIDYING    =  2 << COUNT_BITS;
    private static final int TERMINATED =  3 << COUNT_BITS;

状态间的变化

	 * RUNNING -> SHUTDOWN
     *    On invocation of shutdown(), perhaps implicitly in finalize()
     * (RUNNING or SHUTDOWN) -> STOP
     *    On invocation of shutdownNow()
     * SHUTDOWN -> TIDYING
     *    When both queue and pool are empty
     * STOP -> TIDYING
     *    When pool is empty
     * TIDYING -> TERMINATED
     *    When the terminated() hook method has completed

     Threads waiting in awaitTermination() will return when the state reaches TERMINATED.

状态转换图

在这里插入图片描述
RUNNING:
线程池处在RUNNING状态时,能够接收新任务,以及对已添加的任务进行处理。
线程池被一旦被创建,就处于RUNNING状态,并且线程池中的任务数为0!

SHUTDOWN
线程池处在SHUTDOWN状态时,不接收新任务,但能处理已添加的任务
调用线程池的shutdown()接口时,线程池由RUNNING -> SHUTDOWN

STOP
线程池处在STOP状态时,不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。
调用线程池的shutdownNow()接口时,线程池由(RUNNING or SHUTDOWN ) -> STOP。

TIDYING
当所有的任务已终止,ctl记录的“任务数量”为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。terminated()在ThreadPoolExecutor类中是空的,若用户想在线程池变为TIDYING时,进行相应的处理;可以通过重载terminated()函数来实现。

当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING。
当线程池在STOP状态下,线程池中执行的任务为空时,就会由STOP -> TIDYING。

TERMINATED
线程池彻底终止,就变成TERMINATED状态
线程池处在TIDYING状态时,执行完terminated()之后,就会由 TIDYING -> TERMINATED。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

罗罗的1024

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

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

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

打赏作者

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

抵扣说明:

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

余额充值