线程池详解

本文深入探讨了Java线程池的概念、原理和实现,包括线程池的构造参数、ExecutorService接口、ScheduledExecutorService接口及其优势。还详细介绍了线程池的工作流程,如线程的创建与回收、阻塞队列的选择以及如何确定合适的线程数量。同时,文章分析了线程池的拒绝策略,例如AbortPolicy、CallerRunsPolicy等,并提到了常用阻塞队列如ArrayBlockingQueue和LinkedBlockingQueue的特点。
摘要由CSDN通过智能技术生成

线程池

思考:线程是不是越多越好?

  1. 线程不仅java中是一个对象,每个线程都有自己的工作内存,

    线程创建、销毁需要时间,消耗性能。
    线程过多,会栈用很多内存

  2. 操作系统需要频繁切换线程上下文(大家都想被运行),影响性能。
  3. 如果创建时间+ 销毁时间 > 执行任务时间 就很不合算。
    线程池的推出,就是为了方便的控制线程数量。

一、概念

1、线程池管理器:用于创建并管理线程池,包括创建线程池,销毁线程池,添加新任务;
2、工作线程:线程池中线程,可以循环的执行任务,在没有任务时处于等待状态;
3、任务接口:每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
4、任务队列:用于存放没有处理的任务。提供一种缓冲机制。
在这里插入图片描述

二、线程池原理

1、线程池 - 类的层次结构

在这里插入图片描述
Executor是一个接口,它是Executor框架的基础,它将任务的提交与任务的执行分离开来。

ExecutorService接口继承了Executor,在其上做了一些shutdown()、submit()的扩展,可以说是真正的线程池接口;

AbstractExecutorService抽象类实现了ExecutorService接口中的大部分方法;

ThreadPoolExecutor是线程池的核心实现类,用来执行被提交的任务。

ScheduledExecutorService接口继承了ExecutorService接口,提供了带"周期执行"功能ExecutorService;

ScheduledThreadPoolExecutor是一个实现类,可以在给定的延迟后运行命令,或者定期执行命令。ScheduledThreadPoolExecutor比Timer更灵活,功能更强大。

Future接口和实现Future接口的FutureTask类,代表异步计算的结果。

Runnable接口和Callable接口的实现类,都可以被ThreadPoolExecutor或Scheduled-ThreadPoolExecutor执行。

ThreadPoolExecutor构造函数各参数含义

ThreadPoolExecutor的构造函数:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

1、corePoolSize

线程池中的核心线程数,当提交一个任务时,线程池创建一个新线程执行任务,直到当前线程数等于corePoolSize;
如果当前线程数为corePoolSize,继续提交的任务被保存到阻塞队列中,等待被执行;
如果执行了线程池的prestartAllCoreThreads()方法,线程池会提前创建并启动所有核心线程。

2、maximumPoolSize

线程池中允许的最大线程数。如果当前阻塞队列满了,且继续提交任务,则创建新的线程执行任务,前提是当前线程数小于maximumPoolSize

3、keepAliveTime
线程空闲时的存活时间,即当线程没有任务执行时,继续存活的时间。默认情况下,该参数只在线程数大于corePoolSize时才有用

4、TimeUnit
keepAliveTime的时间单位

5、workQueue

workQueue必须是BlockingQueue阻塞队列。当线程池中的线程数超过它的corePoolSize的时候,线程会进入阻塞队列进行阻塞等待。通过workQueue,线程池实现了阻塞功能

6、ThreadFactory

创建线程的工厂类,不传有默认工厂Executors.defaultThreadFactory()
在这里插入图片描述
我们可以通过线程工厂设置创建的线程的执行线程组,线程的名字(设置线程名字对排查问题非常有用),是否为守护线程,优先级等。

7、拒绝策略
指的是线程池忙,而且任务队列满这种情况下我们就要执行各种各样的拒绝策略,jdk默认提供了四种拒绝策略,也是可以自定义的。

1:Abort:抛异常

2:Discard:扔掉,不抛异常

3:DiscardOldest:扔掉排队时间最久的

4:CallerRuns:调用者处理服务
源码如下:


    /**
     * A handler for rejected tasks that runs the rejected task
     * directly in the calling thread of the {@code execute} method,
     * unless the executor has been shut down, in which case the task
     * is discarded.
     */
    public static class CallerRunsPolicy implements RejectedExecutionHandler {
   
        /**
         * Creates a {@code CallerRunsPolicy}.
         */
        public CallerRunsPolicy() {
    }

        /**
         * Executes task r in the caller's thread, unless the executor
         * has been shut down, in which case the task is discarded.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
   
            if (!e.isShutdown()) {
   
                r.run();
            }
        }
    }

    /**
     * A handler for rejected tasks that throws a
     * {@code RejectedExecutionException}.
     */
    public static class AbortPolicy implements RejectedExecutionHandler {
   
        /**
         * Creates an {@code AbortPolicy}.
         */
        public AbortPolicy() {
    }

        /**
         * Always throws RejectedExecutionException.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         * @throws RejectedExecutionException always
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
   
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejecte
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值