除了可以通过ThreadPoolExecutor自定义线程池外,同Stream API中的Collectors一样,多线程里的Executors类也提供了一组相关的线程池工具,可以直接拿来用,不用考虑用什么队列合适的问题。

Javac除了传统的四大线程池工具:

1、newFixedThreadPool定长线程池

2、newCachedThreadPool缓存线程池

3、newSingleThreadExecutor单线程线程池

4、newScheduledThreadPool任务调度线程池

还包括了Java8新增的newWorkStealingPool抢占式线程池,目前这个用的不多,还是以之前的四大类线程池为主。

一、newFixedThreadPool

newFixedThreadPool定长线程池,顾名思义,就是它的线程池的大小是固定的,好比一个水池只能装10个立方的水量,11个立方肯定就装不下了。在newFixedThreadPool定长线程池中,c=m(也就是corePoolSize = maximumPoolSize),默认为无界队列,用代码来示例:

// 定长线程池
ExecutorService service1 = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
System.out.println("创建线程 " + i);
service1.execute(() -> System.out.println("当前线程 " + Thread.currentThread().getName()));
}
service1.shutdown();

可以看到,虽然创建了10个线程,但始终只有3个在工作。定长线程池在实际中用的比较多,尤其是一些可估算工作量的任务时。它的程序流程图是这样的:

二、newCachedThreadPool

newCachedThreadPool缓存线程池不会限制池中的线程数量,可以无限往里增加,直到线程数量超出最大整数范围,一般不会用这种方式,因为可能会因为程序故障而把机器拖垮。代码也很简单:

// 缓存线程池
ExecutorService service2 = Executors.newCachedThreadPool();
for (int i = 0; i < 1_000_000_000; i++) {
System.out.println("创建线程 " + i);
service2.execute(() -> System.out.println("当前线程 " + Thread.currentThread().getName()));
}
service2.shutdown();

我希望创造10亿个线程,计算机照单全收。我花了很长时间,它都没有停下来的意思

所以我只好强制让它休息了。

它的程序流程图是这样的:

三、newSingleThreadExecutor

newSingleThreadExecutor单线程线程池是定长线程池的一个特例,它的线程池长度始终为1,也就是c=m=1,它的代码:

// 单线程线程池
ExecutorService service3 = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
System.out.println("创建线程 " + i);
service3.execute(() -> System.out.println("当前线程 " + Thread.currentThread().getName()));
}
service3.shutdown();

执行后可以看到,它始终只能创建一个线程。

四、newScheduledThreadPool

最后一个是任务调度线程池,顾名思义,需要执行某些任务调度时可以用到,例如:3个线程每秒执行1次的(仅执行1次):

// 任务调度线程池
ScheduledExecutorService service4 = Executors.newScheduledThreadPool(3);
for (int i = 0; i < 10; i++) {
// 延迟1秒后执行,仅执行1次
service4.schedule(() -> System.out.println("当前线程 " + Thread.currentThread().getName()),
1,
TimeUnit.SECONDS);
}
service4.shutdown();

或者3个线程每3秒各执行1次的:

// 任务调度线程池
ScheduledExecutorService service5 = Executors.newScheduledThreadPool(3);
for (int i = 0; i < 10; i++) {
// 延迟1秒后执行,每3秒执行1次
service4.scheduleAtFixedRate(() -> System.out.println("当前线程 " + Thread.currentThread().getName()),
1,
3,
TimeUnit.SECONDS);
}
service5.shutdown();

线程池的基本内容其实并不多,主要还是要在日常开发中实际使用,多用多练才能熟能生巧。

Java多线程-ThreadPool线程池-3(五)的更多相关文章

  1. Java多线程-ThreadPool线程池(三)

    开完一趟车完整的过程是启动.行驶和停车,但老司机都知道,真正费油的不是行驶,而是长时间的怠速.频繁地踩刹车等动作.因为在速度切换的过程中,发送机要多做一些工作,当然就要多费一些油. 而一个Java线程 ...

  2. Java多线程-ThreadPool线程池-2(四)

    线程池是个神器,用得好会非常地方便.本来觉得线程池的构造器有些复杂,即使讲清楚了对今后的用处可能也不太大,因为有一些Java定义好的线程池可以直接使用.但是(凡事总有个但是),还是觉得讲一讲可能跟有助 ...

  3. Java多线程与线程池技术

    一.序言 Java多线程编程线程池被广泛使用,甚至成为了标配. 线程池本质是池化技术的应用,和连接池类似,创建连接与关闭连接属于耗时操作,创建线程与销毁线程也属于重操作,为了提高效率,先提前创建好一批 ...

  4. Java 多线程:线程池

    Java 多线程:线程池 作者:Grey 原文地址: 博客园:Java 多线程:线程池 CSDN:Java 多线程:线程池 工作原理 线程池内部是通过队列结合线程实现的,当我们利用线程池执行任务时: ...

  5. java多线程:线程池原理、阻塞队列

    一.线程池定义和使用 jdk 1.5 之后就引入了线程池. 1.1 定义 从上面的空间切换看得出来,线程是稀缺资源,它的创建与销毁是一个相对偏重且耗资源的操作,而Java线程依赖于内核线程,创建线程需 ...

  6. java多线程、线程池及Spring配置线程池详解

    1.java中为什么要使用多线程使用多线程,可以把一些大任务分解成多个小任务来执行,多个小任务之间互不影像,同时进行,这样,充分利用了cpu资源.2.java中简单的实现多线程的方式 继承Thread ...

  7. JAVA多线程(三) 线程池和锁的深度化

    github演示代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-servic ...

  8. JAVA中创建线程池的五种方法及比较

    之前写过JAVA中创建线程的三种方法及比较.这次来说说线程池. JAVA中创建线程池主要有两类方法,一类是通过Executors工厂类提供的方法,该类提供了4种不同的线程池可供使用.另一类是通过Thr ...

  9. Java多线程和线程池

    转自:http://blog.csdn.net/u013142781/article/details/51387749 1.为什么要使用线程池 在Java中,如果每个请求到达就创建一个新线程,开销是相 ...

  10. Java多线程之线程池详解

    前言 在认识线程池之前,我们需要使用线程就去创建一个线程,但是我们会发现有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因 ...

随机推荐

  1. AtCoder Beginner Contest 185 题解

    A - ABC Preparation 排序找出最小值 int main() { ios_base::sync_with_stdio(false), cin.tie(0); vector<int ...

  2. SAE 联合乘云至达与谱尼测试携手共同抗疫

    作者 | 营火.计缘.张祖旺 前言 当前疫情形势依然严峻,各行各业众志成城,携手抗疫.新冠病毒核酸检测筛查是疫情防控的重要一环,如何应对疫情的不断反复,以及每日数以万计的核酸检测结果成为每个检测公司的 ...

  3. vue计算属性computed传参

    需求:根据不同的状态status,显示不同颜色的边框

  4. C# 通过ServiceStack 操作Redis——Hash类型的使用及示例

    接着上一篇,下面转到hash类型的代码使用 Hash:结构 key-key-value,通过索引快速定位到指定元素的,可直接修改某个字段 /// <summary> /// Hash:类似 ...

  5. ElasticSearch 映射类型及数据类型区分

    本文为博主原创,未经允许不得转载: 1.ES 中的映射可以分为动态映射和静态映射 动态映射:在关系数据库中,需要事先创建数据库,然后在该数据库下创建数据表,并创建表字段.类型.长度.主键等,最后才能基 ...

  6. 如何与chatgpt共存

    作为程序员,专注于创造性劳动,而把重复性劳动任务交给chatgpt,要成为 需求 和 chatgpt的桥梁. 人工智能比如chatgpt越来越强,提问能力是人类的天赋,提问能力更为重要.

  7. 问题--VSCODE编写C含scanf无终端跳出

    1.问题 在VSCODE中编写C程序,用到scanf输入时,发现无终端输入数据 2.解决方法 在设置里搜索RunInTerminal,勾选该选项即可

  8. Android——共享参数SharedPreferences

    4数据存储 共享参数SharedPreferences.数据库SQLite.SD卡文件.App的全局内存 4.1共享参数SharedPreferences SharedPreferences是一个轻量 ...

  9. 如何让你的.NET WebAPI程序支持HTTP3?

    下面我将总结构建Http3的经验,以Token Gateway的项目为例,请注意使用Http3之前你需要知道它的限制, Windows Windows 11 版本 22000 或更高版本/Window ...

  10. 【转】国产飞腾D2000:基于A72?

    https://zhuanlan.zhihu.com/p/612054128 China's Phytium D2000: Building on A72? 国产飞腾D2000:基于A72? PS:麒 ...