线程池初解1

线程池初解1

前言

  1. 为什么使用线程池
    1. 降低资源消耗:线程的创建和销毁是比较消耗资源的操作,频繁地创建和销毁线程会增加系统的开销。使用线程池可以避免频繁地创建和销毁线程,重复利用线程对象,降低资源消耗。
    2. 提高响应速度:线程池中的线程是预先创建好的,当有任务到来时,可以立即执行,避免了线程创建的开销,提高了任务的响应速度。
    3. 控制并发数量:线程池可以限制同时执行的线程数量,避免系统资源被耗尽,防止因并发数量过大导致系统崩溃。
    4. 提高程序的可维护性:使用线程池可以将任务的执行和线程的管理分离,使得程序结构更清晰、更易于维护。
    5. 提供任务队列:线程池通常会提供一个任务队列,用于存放等待执行的任务,避免任务的丢失,提高任务的处理能力。
    6. 提供线程池管理功能:线程池可以提供线程的生命周期管理、线程的状态监控、异常处理等功能,方便对线程的管理和监控。
  2. java中创建一个线程的方法
    1. 实现Runnable接口(无返回值)
    2. 实现Callable接口(有返回值)
    3. 继承Thread类(和1一样,因为Thread类也实现了Runnable接口)

源码解析

Executor接口

执行已提交 Runnable 任务的对象。此接口提供了一种将任务提交与每个任务的运行机制解耦的方法,包括线程使用、调度等细节。通常使用 An Executor 而不是显式创建线程。Executor接口的实现类通常是线程池,通过将任务提交给线程池来执行。

 public interface Executor {

    /**
     * 该任务执行没有提供返回值
     */
    void execute(Runnable command);
} 

ExecutorService接口

ExecutorService继承了Executor,是一个更完整的接口新增了有返回值的submit方法以及可以关闭线程池的shutdown和shutdownNow方法,还有批量处理多个任务的的方法

public interface ExecutorService extends Executor {

    /**
     * 关闭线程池,不会接收新的任务,但是任务队列中的任务还会继续处理
     */
    void shutdown();

    /**
     * 立刻关闭线程池,不会接受新的任务,也不会处理任务队列中的任务,尝试停止所有正在执行的任务,
     * 返回等待执行的任务列表
     */
    List<Runnable> shutdownNow();

    /**
     * 线程池是否被关闭
     */
    boolean isShutdown();

    /**
     * 如果所有任务在线程池关闭后都已完成,则返回true。请注意,isTerminated除非先调用 or shutdown shutdownNow 否则永远不会true。
     */
    boolean isTerminated();

    /**
     * 阻塞,直到所有任务在关闭请求后完成执行,或发生超时,或当前线程中断,以先发生者为准
     */
    boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException;

    /**
     * 提交值返回任务以供执行,并返回表示任务的待处理结果的 Future。Future get 的方法将在成功完成后返回任务的结果。
     * 提交一个任务,返回一个Future,通过Future.get()获取任务的返回结果
     */
    <T> Future<T> submit(Callable<T> task);

    /**
     * 提交要执行的 Runnable 任务,并返回表示该任务的 Future。Future get 的方法将在成功完成后返回给定的结果。
     * Future.get()返回的结果为result
     */
    <T> Future<T> submit(Runnable task, T result);

    /**
     * 提交要执行的 Runnable 任务,并返回表示该任务的 Future。Future get 的方法将在成功完成后返回给定的结果。
     * Future.get()返回的结果为null
     */
    Future<?> submit(Runnable task);

    /**
     * 执行给定的任务,并在全部完成后返回一个 Futures 列表,其中包含它们的状态和结果。 Future.isDone 用于 true 返回列表的每个元素。请注意,已完成的	   * 任务可能已正常终止,也可能因引发异常而终止。如果在此操作过程中修改了给定的集合,则此方法的结果未定义。
     */
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException;

    /**
     * 执行给定的任务,当所有任务全部完成或超时到期时(以先发生者为准),返回一个 Futures 列表,其中包含其状态和结果。 Future.isDone 用于 true 返回列      * 表的每个元素。返回后,未完成的任务将被取消。请注意,已完成的任务可能已正常终止,也可能因引发异常而终止。如果在此操作过程中修改了给定的集合,则此方          * 法的结果未定义。
     */
    <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;
}

AbstractExecutorService接口

AbstractExecutorServiceExecutorService接口的一个抽象实现类,它提供了ExecutorService接口的部分实现。ExecutorService是Java中用于管理线程池的接口,可以用来执行异步任务。

AbstractExecutorService提供了一些方法的默认实现,简化了自定义线程池的实现。它允许子类只实现核心的执行逻辑,而其他方法如submitinvokeAllinvokeAny等则已经有了默认实现。(模板方法)

提供执行方法的ExecutorService默认实现。submit此类使用 RunnableFuture 返回的 实现 newTaskFor和 invokeAny invokeAll 方法,该方法默认为FutureTask此包中提供的类。例如,的实现submit(Runnable)创建一个执行并返回的关联RunnableFuture。子类可以重写newTaskFor方法以返回 RunnableFuture 以外的实现FutureTask.

public abstract class AbstractExecutorService implements ExecutorService {

    /**
     * 返回给定可运行对象和默认值的 a RunnableFuture 。实例为FutureTask
     * 子类可重写此方法返回其他的RunnableFuture实例
     */
    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        return new FutureTask<T>(runnable, value);
    }

    /**
     * 返回给定可调用任务的 a RunnableFuture 。实例为FutureTask
     * 子类可重写此方法返回其他的RunnableFuture实例
     */
    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }

    /**
     * submit方法接收Runnable返回Future,返回的Future是RunnableFuture接口,实例为FutureTask
     */
    public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }

    /**
     * submit方法接收Runnable,result返回Future,返回的Future是RunnableFuture接口,实例为FutureTask
     */
    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task, result);
        execute(ftask);
        return ftask;
    }

    /**
     * submit方法接收Callable返回Future,返回的Future是RunnableFuture接口,实例为FutureTask
     */
    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }

    /**
     * the main mechanics of invokeAny.
     */
    private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
                              boolean timed, long nanos)
        throws InterruptedException, ExecutionException, TimeoutException {
        if (tasks == null)
            throw new NullPointerException();
        int ntasks = tasks.size();
        if (ntasks == 0)
            throw new IllegalArgumentException();
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
        //完成的调用执行服务 使用QueueingFuture作为任务单元 重写了FutureTask的Done方法 将已经完成的任务放到一个阻塞队列中
        ExecutorCompletionService<T> ecs =
            new ExecutorCompletionService<T>(this);

        // For efficiency, especially in executors with limited
        // parallelism, check to see if previously submitted tasks are
        // done before submitting more of them. This interleaving
        // plus the exception mechanics account for messiness of main
        // loop.

        try {
            // Record exceptions so that if we fail to obtain any
            // result, we can throw the last exception we got.
            ExecutionException ee = null;
            //超时时间点
            final long deadline = timed ? System.nanoTime() + nanos : 0L;
            Iterator<? extends Callable<T>> it = tasks.iterator();

            // Start one task for sure; the rest incrementally
            futures.add(ecs.submit(it.next()));
            //剩余任务数
            --ntasks;
            //正在执行的任务数
            int active = 1;

            for (;;) { //自旋
                //在已完成的任务阻塞队列中取出一个
                Future<T> f = ecs.poll();
                //还没有完成的任务
                if (f == null) {
                    if (ntasks > 0) {
                        --ntasks;
                        futures.add(ecs.submit(it.next()));
                        ++active;
                    }
                    //所有任务都出现了异常
                    else if (active == 0)
                        break;
                    //当任务已经全部去执行时 超时等待获取结果
                    else if (timed) {
                        f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
                        if (f == null) 
                            throw new TimeoutException();
                        nanos = deadline - System.nanoTime();
                    }
                    else
                        //当任务已经全部去执行时 阻塞 获取结果 直到有任务完成
                        f = ecs.take();
                }
                //已经有完成的任务了
                if (f != null) {
                    --active;
                    try {
                        //返回任务结果
                        return f.get();
                    } catch (ExecutionException eex) {
                        //执行异常 出现异常后不会返回 找到执行成功的任务
                        ee = eex;
                    } catch (RuntimeException rex) {
                        //执行异常 出现异常后不会返回 找到执行成功的任务
                        ee = new ExecutionException(rex);
                    }
                }
            }

            if (ee == null)
                ee = new ExecutionException();
            throw ee;

        } finally {
            for (int i = 0, size = futures.size(); i < size; i++)
                //取消任务
                futures.get(i).cancel(true);
        }
    }
	
    public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException {
        try {
            return doInvokeAny(tasks, false, 0);
        } catch (TimeoutException cannotHappen) {
            assert false;
            return null;
        }
    }

    public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                           long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
        return doInvokeAny(tasks, true, unit.toNanos(timeout));
    }

    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException {
        if (tasks == null)
            throw new NullPointerException();
        //一个任务数组
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
        boolean done = false;
        try {
            //遍历任务数组执行
            for (Callable<T> t : tasks) {
                RunnableFuture<T> f = newTaskFor(t);
                futures.add(f);
                execute(f);
            }
            //遍历futures列表
            for (int i = 0, size = futures.size(); i < size; i++) {
                Future<T> f = futures.get(i);
                //对于没有完成的任务执行 get 阻塞当前线程
                if (!f.isDone()) {
                    try {
                        f.get();
                    } catch (CancellationException ignore) {
                    } catch (ExecutionException ignore) {
                    }
                }
            }
            //所有的任务全部完成
            done = true;
            return futures;
        } finally {
            //没有完成 则操作future进行取消
            if (!done)
                for (int i = 0, size = futures.size(); i < size; i++)
                    //已经完成的任务取消不受影响
                    futures.get(i).cancel(true);
        }
    }

    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                         long timeout, TimeUnit unit)
        throws InterruptedException {
        if (tasks == null)
            throw new NullPointerException();
        long nanos = unit.toNanos(timeout);
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
        boolean done = false;
        try {
            for (Callable<T> t : tasks)
                futures.add(newTaskFor(t));
            //截至时间点
            final long deadline = System.nanoTime() + nanos;
            final int size = futures.size();

            // Interleave time checks and calls to execute in case
            // executor doesn't have any/much parallelism.
            for (int i = 0; i < size; i++) {
                execute((Runnable)futures.get(i));
                //剩余时间
                nanos = deadline - System.nanoTime();
                if (nanos <= 0L)
                    //超时直接返回
                    return futures;
            }

            for (int i = 0; i < size; i++) {
                Future<T> f = futures.get(i);
                if (!f.isDone()) {
                    if (nanos <= 0L)
                        return futures;
                    try {
                        //在给定的时间内获取结果
                        f.get(nanos, TimeUnit.NANOSECONDS);
                    } catch (CancellationException ignore) {
                    } catch (ExecutionException ignore) {
                    } catch (TimeoutException toe) {
                        //执行超时直接返回
                        return futures;
                    }
                    //剩余时间
                    nanos = deadline - System.nanoTime();
                }
            }
            done = true;
            return futures;
        } finally {
            if (!done)
                for (int i = 0, size = futures.size(); i < size; i++)
                    //已经完成的任务取消不受影响
                    futures.get(i).cancel(true);
        }
    }

}
  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值