Java多线程实现之Executor详解

 更新时间:2023年08月26日 09:36:56   作者:not coder  
这篇文章主要介绍了Java多线程实现之Executor详解,Executor 给他一个 Runnable,他就能自动很安全的帮你把这个线程执行完毕
Executor 通过创建线程池的方式来管理线程,需要的朋友可以参考下

Executor 线程实现

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("runnable 线程开始执行");
            }
        };
        Executor executor = Executors.newCachedThreadPool();
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);

1 Executor 简介

  • Executor 给他一个 Runnable,他就能自动很安全的帮你把这个线程执行完毕
  • Executor 通过创建线程池的方式来管理线程
  • Executor 有五种创建线程池的方式,其中 newCachedThreadPool() 是一种非常简单的线程池创建方式
  • Executor 有两种结束方式,shutDown() 和 shutDownNow()
    • shutDown 会将当前正在执行的和排队中的线程执行完毕后结束,并且不允许有新的线程加入到待执行队列中
    • shutDownNow 会立即结束执行,采取的是一种比较安全的结束方式:interrupt()

2 Executor 中 其他几种创建线程池的方式

2.1 Executor 中的第一种线程池创建方式 newCachedThreadPool()

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

newCachedThreadPool() 的实现:

在 newCachedThreadPool 中,会直接返回一个 ThreadPoolExecutor,这里解释一下创建 ThreadPoolExecutor 的几个参数:

/**
	 * @param corePoolSize 代表默认线程数,或者说最低线程数,也就是此线程池创建后里面立马会有几个线程的数量
	 * @param maximumPoolSize 代表最大线程数,超过此线程数量则排队等待执行,排队线程放入最后一个参数中
	 * @param keepAliveTime 表示默认线程数量外的已经创建出来的线程在处于空闲状态下,被回收前需要等待的时间
	 * @param unit 表示第三个时间值的单位
	 * @param workQueue 用于盛放多余任务的线程队列
	 */
	ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue)
  1. 第一个参数代表默认线程数,或者说最低线程数,也就是此线程池创建后里面立马会有几个线程的数量
  2. 第二个参数代表最大线程数,超过此线程数量则排队等待执行,排队线程放入最后一个参数中
  3. 第三个参数表示默认线程数量外的已经创建出来的线程在处于空闲状态下,被回收前需要等待的时间
  4. 第四个参数表示第三个时间值的单位
  5. 第五个参数用于盛放多余任务的线程队列

例:

假如说传入的值分别为 5,20,10L,TimeUnit.SECONDS,new SynchronousQueue< Runnable>()

则表示,创建一个默认数量为 5 的线程池,这个线程池最多允许 20 条线程同时工作,如果超过 20 个则存放进队列中等待这 20 个线程腾出位置,每个线程执行完毕都去队列中取新的任务并执行,如果队列中没有新的任务,则线程等待 10 秒,如果 10 后仍然没有新的任务,则线程会被回收,一直回收到只剩余 5 个线程

2.1 Executor.newSingleThreadExecutor()

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

通过前两个参数可以看出,这是创建单线程的线程池,也就是说这个线程池中只有一个线程,并且最多也只能有一个线程,应用场景比较少。

2.2 Executor.newFixedThreadPool()

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

创建固定数量线程的线程池,通过前两个参数可以看出,传入的参数被同时应用中前两个参数中,这就意味着我创建一个线程池,里面的默认线程数和最大线程数一致

并且不能扩容、不被回收,一直放在那里,表面上可能比较合理,但实际的应用场景也很少

在处理瞬时爆发性任务时会能用得到,例:

        Runnable precessImageRunner = new Runnable() {
            @Override
            public void run() {
                System.out.println("开始处理图片了,我很耗时,,,,");
            }
        };
        List<Bitmap> bitmaps = new ArrayList<>();
        ExecutorService fixedExecutor = Executors.newFixedThreadPool(30);
        for (Bitmap bitmap : bitmaps) {
            fixedExecutor.execute(precessImageRunner);
        }
        fixedExecutor.shutdown();

fixedExecutor.shutdown() 来防止永远不回收造成资源浪费的情况

Executor.newScheduledThreadPool()

创建一个延迟的线程池

Executor.newSingleThreadScheduledExecutor()

创建一个延迟的单线程线程池

总结

以上就是 Executor 的简介及 Executor 五种创建线程的方式,你学废了吗?

复习一遍:

//  Executor 五种创建线程的方式
        Executors.newCachedThreadPool();
        Executors.newSingleThreadExecutor();
        Executors.newFixedThreadPool();
        Executors.newScheduledThreadPool();
        Executors.newSingleThreadScheduledExecutor();

到此这篇关于Java多线程实现之Executor详解的文章就介绍到这了,更多相关Java多线程Executor内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MybatisPlus中的多表条件排序查询

    MybatisPlus中的多表条件排序查询

    这篇文章主要介绍了MybatisPlus中的多表条件排序查询,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • Springboot和Jpa实现学生CRUD操作代码实例

    Springboot和Jpa实现学生CRUD操作代码实例

    这篇文章主要介绍了Springboot和Jpa实现学生CRUD操作代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • java使用电脑摄像头识别二维码

    java使用电脑摄像头识别二维码

    这篇文章主要为大家详细介绍了java使用电脑摄像头识别二维码,从摄像头获取图像,再根据图片解析出二维码信息,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-10-10
  • Spring Boot集成Redis实现缓存机制(从零开始学Spring Boot)

    Spring Boot集成Redis实现缓存机制(从零开始学Spring Boot)

    这篇文章主要介绍了Spring Boot集成Redis实现缓存机制(从零开始学Spring Boot),需要的朋友可以参考下
    2017-04-04
  • SpringCloud应用idea实现可相互调用的多模块程序详解

    SpringCloud应用idea实现可相互调用的多模块程序详解

    IDEA 全称 IntelliJ IDEA,是java编程语言的集成开发环境。IntelliJ在业界被公认为最好的Java开发工具,尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(git、svn等)、JUnit、CVS整合、代码分析、 创新的GUI设计等方面的功能可以说是超常的
    2022-07-07
  • java eclipse 中文件的上传和下载示例解析

    java eclipse 中文件的上传和下载示例解析

    这篇文章主要介绍了eclipse java中文件的上传和下载示例解析,文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的。对此感兴趣的小伙伴可以了解一下
    2020-07-07
  • Java Swing实现的定制TextField功能示例

    Java Swing实现的定制TextField功能示例

    这篇文章主要介绍了Java Swing实现的定制TextField功能,结合实例形式分析了java swing组件TextField相关属性功能与设置操作技巧,需要的朋友可以参考下
    2018-01-01
  • 基于线程池的工作原理与源码解读

    基于线程池的工作原理与源码解读

    下面小编就为大家分享一篇基于线程池的工作原理与源码解读,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • SpringMVC使用注解实现登录功能

    SpringMVC使用注解实现登录功能

    这篇文章主要为大家详细介绍了SpringMVC使用注解实现登录功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-09-09
  • @Inject注解和@Named注解注入失败

    @Inject注解和@Named注解注入失败

    在学习Spring框架时,按照官网介绍的JSR-333标准注释(依赖注入)操作,但运行时找不到bean并报错,后发现是pom文件中版本不对,将版本降低后,问题解决,总结了个人经验,原来是不同版本的包名不同导致问题发生
    2026-05-05

最新评论