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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 为什么mybatis中的SqlSession一定要关闭

    为什么mybatis中的SqlSession一定要关闭

    这篇文章主要介绍了为什么mybatis中的SqlSession一定要关闭,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Geotools实现shape文件的写入功能

    Geotools实现shape文件的写入功能

    Geotools作为开源的Java GIS三方库,已经成为GIS服务器端的主流开源库,其功能非常强大,涉及到GIS业务的方方面面,其中就包括GIS数据的读写,今天小编就借助Geotools来实现shape数据的写入,需要的朋友可以参考下
    2023-08-08
  • Java LinkedList实现班级信息管理系统

    Java LinkedList实现班级信息管理系统

    这篇文章主要为大家详细介绍了Java LinkedList实现班级信息管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • 谷歌二维码引擎com.google.zxing二维码生成与解析

    谷歌二维码引擎com.google.zxing二维码生成与解析

    这篇文章主要给大家介绍了关于谷歌二维码引擎com.google.zxing二维码生成与解析的相关资料,zxing是google开源的二维码生成和解析工具,需要的朋友可以参考下
    2023-07-07
  • 详解SpringMVC的类型转换及验证方法

    详解SpringMVC的类型转换及验证方法

    在本篇文章里面我们给大家详细分析了SpringMVC的类型转换及验证方法的相关知识,对此有需要的朋友们学习下吧。
    2018-10-10
  • Java实现学生管理系统详解

    Java实现学生管理系统详解

    这篇文章主要为大家详细介绍了Java实现学生管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-10-10
  • java 重试框架 sisyphus 入门介绍

    java 重试框架 sisyphus 入门介绍

    sisyphus 综合了 spring-retry 和 gauva-retrying 的优势,使用起来也非常灵活,本文给大家介绍java 重试框架 sisyphus 入门相关知识,感兴趣的朋友一起看看吧
    2021-10-10
  • java实现通讯录管理系统

    java实现通讯录管理系统

    这篇文章主要为大家详细介绍了java实现通讯录管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • Spring Batch实现批量处理

    Spring Batch实现批量处理

    本文主要介绍了Spring Batch进行批量处理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • 简单了解Mybatis如何实现SQL防注入

    简单了解Mybatis如何实现SQL防注入

    这篇文章主要介绍了简单了解Mybatis如何实现SQL防注入,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01

最新评论