03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)

目录

  • ThreadPoolExecutor 线程池源码剖析------线程池工具类(ExecutorService)
    • 方法
      • shutdown()
      • shutdownNow()
      • submit(Callable task)
      • submit(Runnable task)
      • submit(Runnable task, T result)
    • 实现类
      • Executors.newCachedThreadPool()
      • Executors.newFixedThreadPool()
      • Executors.newSingleThreadExecutor()
      • Executors.newScheduledThreadPool()
        • schedule 方法
        • scheduleAtFixedRate 方法
        • scheduleWithFixedDelay
      • Executors.newSingleThreadScheduledExecutor()
    • 异步计算结果 (Future)
      • get()
      • get(long timeout, TimeUnit unit)
      • cancel(boolean mayInterruptIfRunning)
      • isCancelled()
      • isDone()
    • 代码

ThreadPoolExecutor 线程池源码剖析------线程池工具类(ExecutorService)

ExecutorService接口是 java 内置的线程池接口,通过学习接口中的方法,可以快速的掌握 java 内置线程池 的基本使用

原本创建线程池的Demo,需要设置很多参数,现在使用 ExecutorService 类,就可以节省很多设置。

如图:这是直接创建ThreadPoolExecutor 线程池的demo:
需要设置这些参数等:
03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第1张图片

03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第2张图片
下面使用 ExecutorService 类 来快速使用线程池,减少原本的一些参数定义。


方法


shutdown()

关闭线程池的方法,前面已经演示过了

启动一次顺序关闭,执行以前提交的任务,但不接受新任务


shutdownNow()

关闭线程池的方法,前面已经演示过了

停止所有正在执行的任务,暂停处理正在等待的任务,并返回等待执行的任务列表


submit(Callable task)

相当于之前的execute方法。也是往线程提交一个任务。
这里Callable是有返回值的


submit(Runnable task)

执行 Runnable 任务,并返回一个表示该任务的 Future。


submit(Runnable task, T result)

执行 Runnable 任务,并返回一个表示该任务的 Future。

实现类


Executors.newCachedThreadPool()

创建一个默认的线程池对象,里面的线程可重用,且在第一次使用时才创建。

cache:缓存】隐藏


代码演示:
用这个方法创建的线程池,适用于:不需要定制最大线程数和最小线程这些,来个任务就创建个线程,任务做完就取新的任务。
工作线程创建多少不用我们管。

03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第3张图片


Executors.newFixedThreadPool()

创建一个可重用固定线程数的线程池
Fixed:固定的

如图:最大线程数和最小核心线程数的参数是同一个,是固定的。

03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第4张图片


Executors.newSingleThreadExecutor()

创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。

Single:单个的、单一的

03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第5张图片


Executors.newScheduledThreadPool()

创建一个可重用固定线程数的线程池且允许延迟运行或定期执行任务;

这个方法是可以多个线程执行的。

schedule 方法

Scheduled:定时、预定、定于

定时的话,得用这个 ScheduledExecutorService 类来创建线程池,才有对应的定时方法。

任务添加到线程池5,定时5秒后再执行
应用场景:比如超时支付

03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第6张图片


scheduleAtFixedRate 方法

fixed:固定
rate:速度

同一个任务,周期性的执行该任务。
任务提交到线程池后,最开始隔3秒后执行,后面就周期性的每隔5秒执行一次。

03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第7张图片

03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第8张图片


任务提交到线程池后,最开始隔3秒后执行,后面就周期性的每隔5秒执行一次

设置情况一:任务执行时间需要2秒

得出结论:只要进入到这个run方法,就会开始计时,不会管任务执行多久

03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第9张图片


设置情况二:任务执行时间需要10秒,大于周期性时间设置的5秒
得出结论:
只要进入到任务的run方法,就开始计时,不会管任务执行多久,如果任务执行时间已经超过大于周期性时间,那么该任务执行完后,就会立即继续执行。
03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第10张图片


scheduleWithFixedDelay

任务执行时间需要2秒,大于周期性时间设置的5秒

可以看出:这个方法是等任务执行完后,才开始计时的。

适用场景:定时器功能

03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第11张图片

03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第12张图片


Executors.newSingleThreadScheduledExecutor()

创建一个单线程执行程序,它允许在给定延迟后运行命令或者定期地执行。

跟上一个方法差不多,区别就是:这个方法是单线程执行的。

03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第13张图片


异步计算结果 (Future)

上面的在使用这个 java内置线程池时,没有考虑线程计算的结果,但开发中,我们有时需要利用线程进行一些计算,然后获取这些计算的结果,而java中的Future接口就是专门用于描述异步计算结果的,我们可以通过Future 对象获取线程计算的结果;


get()

如有必要,等待计算完成,然后获取其结果。

03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第14张图片

执行任务的线程因为睡眠5,这期间main线程已经执行了future.get()代码了,那么future.get()在任务还没执行完时能拿到返回值或是null吗?

从源码看,future.get() 如果取不到值会进行阻塞,然后任务线程执行完后,就会唤醒已经阻塞的future.get(),然后future.get()获取到值。

03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第15张图片


还可以设置超时时间:

get(long timeout, TimeUnit unit)

如有必要,最多等待为使计算完成所给定的时间之后,获取其结果(如果结果可用)。

任务执行5秒,get的超时时间是6秒,可以正常获取到值

03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第16张图片


如果任务执行时间是5秒,超时时间设置为4秒。那么就会报超时的错

03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第17张图片


cancel(boolean mayInterruptIfRunning)

试图取消对此任务的执行。

future.cancel(true); 就是中断任务线程
03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第18张图片


isCancelled()

如果在 任务执行完成前 将其取消,则返回 true。

03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第19张图片


执行到 future.isCancelled() 这个代码时,如果任务还没被中断,则返回false
03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第20张图片


isDone()

如果任务已完成,则返回 true。
03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第21张图片


超时没执行完,直接报错,后续代码也不会执行了
03、ThreadPoolExecutor 线程池源码完整剖析------线程池工具类(ExecutorService)_第22张图片

代码

package cn.ljh.algorithmic;

import lombok.SneakyThrows;

import java.util.Date;
import java.util.concurrent.*;

public class ExecutorServiceDemo02
{
    @SneakyThrows
    public static void main(String[] args)
    {
        //创建一个线程池
        ExecutorService service = Executors.newCachedThreadPool();
        //有返回值
        Future<String> future = service.submit(new Callable<String>()
        {
            @Override
            public String call() throws Exception
            {
                System.err.println("线程池线程:当前线程: " + Thread.currentThread().getName());
                TimeUnit.SECONDS.sleep(5);
                return "66666666 线程池里面的线程执行任务后的结果";
            }
        });
        //中断此任务的执行
        //future.cancel(true);
        //如果在任务正常完成前将其取消,则返回 true。执行到这里时,任务没有被中断,返回false
        System.err.println(future.isCancelled());
        System.err.println("main线程:当前线程:"+Thread.currentThread().getName());

        System.err.println("isDone()1 : "+future.isDone());

        //线程返回的结果,还可以设置超时时间
        String result = future.get(4,TimeUnit.SECONDS);

        System.err.println("isDone()2 : "+future.isDone());

        System.err.println("线程返回的结果:" + result);
    }
}

你可能感兴趣的:(Java底层源码,原理系列,线程池,ExecutorService)