多线程

Java线程池"基本架构"

2021-09-15  本文已影响0人  Duanty

我们知道, 在Java中创建线程的代价是非常昂贵的, 需要JVM和OS的配置进行大量的处理工作:

  1. 必须为线程堆栈分配和初始化大量的内存块, 其中至少包含1MB的栈内存.
  2. 需要使用JNI系统调用, 以便在OS中创建和注册本地线程.Java委托操作系统线程处理Java线程

一般开发中, 我们不允许频繁的创建和销毁线程, 常用的阿里开发规范Java版不允许开发人员自行显示的创建线程, 应采用线程池减少系统资源开销.

线程池的好处
a. 提升性能

线程池能独立的负责线程的创建, 维护和分配. 在执行大量的异步任务时不需要自己创建线程, 而是交给线程池去调度. 线程池能使用空闲的线程执行异步任务, 最大限度的提高对已经创建线程的复用性, 提升性能.

b. 线程管理

每个Java线程池都有线程的管理能力. 例: 任务数量, 空闲数量, 执行时间等信息. 对线程进行有效的管理, 提升异步任务的高效调度.


Java线程池架构

线程池类结构

1. Executor接口

异步任务的"执行者"接口, Executor提供了一个execute()来执行已经提交的Runnable执行目标实例. Executor是作为执行者的角色, 目的是提供一种将"任务提交者"和"任务执行者"分开的机制, 它只有一个函数式方法:

public interface Executor {
    void execute(Runnable var1);
}

2. ExecutorService

ExecutorService接口继承自Executor, 它是异步任务的"执行者服务"接口, 对外提供异步任务的接受者服务. ExecutorService提供了接收"接收异步任务并转交给执行者"的方法.

public interface ExecutorService extends Executor {

    /**
     * 关闭执行器, 主要有以下特点:
     * 1. 已经提交给该执行器的任务将会继续执行, 但是不再接受新任务的提交;
     * 2. 如果执行器已经关闭了, 则再次调用没有副作用.
     */
    void shutdown();

    /**
     * 立即关闭执行器, 主要有以下特点:
     * 1. 尝试停止所有正在执行的任务, 无法保证能够停止成功, 但会尽力尝试(例如, 通过 Thread.interrupt中断任务, 但是不响应中断的任务可能无法终止);
     * 2. 暂停处理已经提交但未执行的任务;
     *
     * @return 返回已经提交但未执行的任务列表
     */
    List<Runnable> shutdownNow();

    /**
     * 如果该执行器已经关闭, 则返回true.
     */
    boolean isShutdown();

    /**
     * 判断执行器是否已经【终止】.
     * 仅当执行器已关闭且所有任务都已经执行完成, 才返回true.
     * 注意: 除非首先调用 shutdown 或 shutdownNow, 否则该方法永远返回false.
     */
    boolean isTerminated();

    /**
     * 阻塞调用线程, 等待执行器到达【终止】状态.
     *
     * @return {@code true} 如果执行器最终到达终止状态, 则返回true; 否则返回false
     * @throws InterruptedException if interrupted while waiting
     */
    boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;

    /**
     * 提交一个具有返回值的任务用于执行.
     * 注意: Future的get方法在成功完成时将会返回task的返回值.
     *
     * @param task 待提交的任务
     * @param <T>  任务的返回值类型
     * @return 返回该任务的Future对象
     * @throws RejectedExecutionException 如果任务无法安排执行
     * @throws NullPointerException       if the task is null
     */
    <T> Future<T> submit(Callable<T> task);

    /**
     * 提交一个 Runnable 任务用于执行.
     * 注意: Future的get方法在成功完成时将会返回给定的结果(入参时指定).
     *
     * @param task   待提交的任务
     * @param result 返回的结果
     * @param <T>    返回的结果类型
     * @return 返回该任务的Future对象
     * @throws RejectedExecutionException 如果任务无法安排执行
     * @throws NullPointerException       if the task is null
     */
    <T> Future<T> submit(Runnable task, T result);

    /**
     * 提交一个 Runnable 任务用于执行.
     * 注意: Future的get方法在成功完成时将会返回null.
     *
     * @param task 待提交的任务
     * @return 返回该任务的Future对象
     * @throws RejectedExecutionException 如果任务无法安排执行
     * @throws NullPointerException       if the task is null
     */
    Future<?> submit(Runnable task);

    /**
     * 执行给定集合中的所有任务, 当所有任务都执行完成后, 返回保持任务状态和结果的 Future 列表.
     * 
     * 注意: 该方法为同步方法. 返回列表中的所有元素的Future.isDone() 为 true.
     *
     * @param tasks 任务集合
     * @param <T>   任务的返回结果类型
     * @return 任务的Future对象列表,列表顺序与集合中的迭代器所生成的顺序相同,
     * @throws InterruptedException       如果等待时发生中断, 会将所有未完成的任务取消.
     * @throws NullPointerException       任一任务为 null
     * @throws RejectedExecutionException 如果任一任务无法安排执行
     */
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;

    /**
     * 执行给定集合中的所有任务, 当所有任务都执行完成后或超时期满时(无论哪个首先发生), 返回保持任务状态和结果的 Future 列表.
     */
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException;

    /**
     * 执行给定集合中的任务, 只有其中某个任务率先成功完成(未抛出异常), 则返回其结果.
     * 一旦正常或异常返回后, 则取消尚未完成的任务.
     */
    <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException;

    /**
     * 执行给定集合中的任务, 如果在给定的超时期满前, 某个任务已成功完成(未抛出异常), 则返回其结果.
     * 一旦正常或异常返回后, 则取消尚未完成的任务.
     */
    <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

3. AbstractExecutorService

AbstractExecutorService是一个抽象类, 它实现了ExecutorService接口.
AbstractExecutorService存在的目的是为ExecutorService中的接口提供默认实现

4. ThreadPoolExecutor *

JDK所有线程池实现的父类, 它继承于AbstractExecutorService抽象类.
ThreadPoolExecutor是JUC线程池的核心实现类. 线程的创建和终止需要很大的开销, 线程池中预先提供了指定数量的可重用线程, 所以使用线程池会节省系统资源, 并且每个线程池都维护了一些基础的数据统计, 方便线程的管理和监控.

5. ScheduledExecutorService

ScheduledExecutorService是一个接口, 它继承于ExecutorService. 它是一个可以完成“延时”和“周期性”任务的调度线程池接口, 其功能和Timer/TimerTask类似.
[Timer]Java定时工具类

6. ScheduledThreadPoolExecutor

继承于ThreadPoolExecutor, 它提供了ScheduledExecutorService线程池接口中"延时执行"和"周期执行"等抽象调度方法的具体实现. 类似于Timer, 但是在高并发程序中, ScheduledThreadPoolExecutor的性能要优于Timer.

7. Executors

Executors是一个静态工厂类, 它通过静态工厂方法返回ExecutorService, ScheduledExecutorService等线程池示例对象, 这些静态工厂方法可以理解为一些快捷的创建线程池的方法.

上一篇下一篇

猜你喜欢

热点阅读