美文网首页多线程
Java线程池"基本架构"

Java线程池"基本架构"

作者: Duanty | 来源:发表于2021-09-15 14:50 被阅读0次

    我们知道, 在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等线程池示例对象, 这些静态工厂方法可以理解为一些快捷的创建线程池的方法.

    相关文章

      网友评论

        本文标题:Java线程池"基本架构"

        本文链接:https://www.haomeiwen.com/subject/lkzurltx.html