Java笔试面试-Executors
Executors 可以创建以下六种线程池:
- FixedThreadPool(n):创建一个数量固定的线程池,超出的任务会在队列中等待空闲的线程,可用于控制程序的最大并发数。
- CachedThreadPool():短时间内处理大量工作的线程池,会根据任务数量产生对应的线程,并试图缓存线程以便重复使用,如果限制 60 秒没被使用,则会被移除缓存。
- SingleThreadExecutor():创建一个单线程线程池。
- ScheduledThreadPool(n):创建一个数量固定的线程池,支持执行定时性或周期性任务。
- SingleThreadScheduledExecutor():此线程池就是单线程的 newScheduledThreadPool。
- WorkStealingPool(n):Java 8 新增创建线程池的方法,创建时如果不设置任何参数,则以当前机器处理器个数作为线程个数,此线程池会并行处理任务,不能保证执行顺序。
1.FixedThreadPool 使用
创建固定个数的线程池,具体示例如下:
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);
for (int i = 0; i < 3; i++) {fixedThreadPool.execute(() -> {System.out.println("CurrentTime - " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}});
}
以上程序执行结果如下:
CurrentTime - 2019-06-27 20:58:58CurrentTime - 2019-06-27 20:58:58CurrentTime - 2019-06-27 20:58:59
根据执行结果可以看出,newFixedThreadPool(2) 确实是创建了两个线程,在执行了一轮(2 次)之后,停了一秒,有了空闲线程,才执行第三次。
2.CachedThreadPool 使用
根据实际需要自动创建带缓存功能的线程池,具体代码如下:
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {cachedThreadPool.execute(() -> {System.out.println("CurrentTime - " +LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}});
}
以上程序执行结果如下:
CurrentTime - 2019-06-27 21:24:46CurrentTime - 2019-06-27 21:24:46CurrentTime - 2019-06-27 21:24:46CurrentTime - 2019-06-27 21:24:46CurrentTime - 2019-06-27 21:24:46CurrentTime - 2019-06-27 21:24:46CurrentTime - 2019-06-27 21:24:46CurrentTime - 2019-06-27 21:24:46CurrentTime - 2019-06-27 21:24:46CurrentTime - 2019-06-27 21:24:46
根据执行结果可以看出,newCachedThreadPool 在短时间内会创建多个线程来处理对应的任务,并试图把它们进行缓存以便重复使用。
3.SingleThreadExecutor 使用
创建单个线程的线程池,具体代码如下:
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 3; i++) {singleThreadExecutor.execute(() -> {System.out.println("CurrentTime - " +LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}});
}
以上程序执行结果如下:
CurrentTime - 2019-06-27 21:43:34CurrentTime - 2019-06-27 21:43:35CurrentTime - 2019-06-27 21:43:36
4.ScheduledThreadPool 使用
创建一个可以执行周期性任务的线程池,具体代码如下:
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
scheduledThreadPool.schedule(() -> {System.out.println("ThreadPool:" + LocalDateTime.now());
}, 1L, TimeUnit.SECONDS);
System.out.println("CurrentTime:" + LocalDateTime.now());
以上程序执行结果如下:
CurrentTime:2019-06-27T21:54:21.881ThreadPool:2019-06-27T21:54:22.845
根据执行结果可以看出,我们设置的 1 秒后执行的任务生效了。
5.SingleThreadScheduledExecutor 使用
创建一个可以执行周期性任务的单线程池,具体代码如下:
ScheduledExecutorService singleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor();
singleThreadScheduledExecutor.schedule(() -> {System.out.println("ThreadPool:" + LocalDateTime.now());
}, 1L, TimeUnit.SECONDS);
System.out.println("CurrentTime:" + LocalDateTime.now());
6.WorkStealingPool 使用
Java 8 新增的创建线程池的方式,可根据当前电脑 CPU 处理器数量生成相应个数的线程池,使用代码如下:
ExecutorService workStealingPool = Executors.newWorkStealingPool();
for (int i = 0; i < 5; i++) {int finalNumber = i;workStealingPool.execute(() -> {System.out.println("I:" + finalNumber);});
}
Thread.sleep(5000);
以上程序执行结果如下:
I:0I:3I:2I:1I:4
根据执行结果可以看出,newWorkStealingPool 是并行处理任务的,并不能保证执行顺序。
ThreadPoolExecutor VS Executors
ThreadPoolExecutor 和 Executors 都是用来创建线程池的,其中 ThreadPoolExecutor 创建线程池的方式相对传统,而 Executors 提供了更多的线程池类型(6 种),但很不幸的消息是在实际开发中并不推荐使用 Executors 的方式来创建线程池。
笔试面试题
1.以下程序会输出什么结果?
public static void main(String[] args) {ExecutorService workStealingPool = Executors.newWorkStealingPool();for (int i = 0; i < 5; i++) {int finalNumber = i;workStealingPool.execute(() -> {System.out.print(finalNumber);});}
}
A:不输出任何结果
B:输出 0 到 9 有序数字
C:输出 0 到 9 无需数字
D:以上全对
答:A
题目解析:newWorkStealingPool 内部实现是 ForkJoinPool,它会随着主程序的退出而退出,因为主程序没有任何休眠和等待操作,程序会一闪而过,不会执行任何信息,所以也就不会输出任何结果。
2.Executors 能创建单线程的线程池吗?怎么创建?
答:Executors 可以创建单线程线程池,创建分为两种方式:
- Executors.newSingleThreadExecutor():创建一个单线程线程池。
- Executors.newSingleThreadScheduledExecutor():创建一个可以执行周期性任务的单线程池。
3.Executors 中哪个线程适合执行短时间内大量任务?
答:newCachedThreadPool() 适合处理大量短时间工作任务。它会试图缓存线程并重用,如果没有缓存任务就会新创建任务,如果线程的限制时间超过六十秒,则会被移除线程池,因此它比较适合短时间内处理大量任务。
4.可以执行周期性任务的线程池都有哪些?
答:可执行周期性任务的线程池有两个,分别是:newScheduledThreadPool() 和 newSingleThreadScheduledExecutor(),其中 newSingleThreadScheduledExecutor() 是 newScheduledThreadPool() 的单线程版本。
5.JDK 8 新增了什么线程池?有什么特点?
答:JDK 8 新增的线程池是 newWorkStealingPool(n),如果不指定并发数(也就是不指定 n),newWorkStealingPool() 会根据当前 CPU 处理器数量生成相应个数的线程池。它的特点是并行处理任务的,不能保证任务的执行顺序。
6.newFixedThreadPool 和 ThreadPoolExecutor 有什么关系?
答:newFixedThreadPool 是 ThreadPoolExecutor 包装,newFixedThreadPool 底层也是通过 ThreadPoolExecutor 实现的。
newFixedThreadPool 的实现源码如下:
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(),threadFactory);
}
7.单线程的线程池存在的意义是什么?
答:单线程线程池提供了队列功能,如果有多个任务会排队执行,可以保证任务执行的顺序性。单线程线程池也可以重复利用已有线程,减低系统创建和销毁线程的性能开销。
8.线程池为什么建议使用 ThreadPoolExecutor 创建,而非 Executors?
答:使用 ThreadPoolExecutor 能让开发者更加明确线程池的运行规则,避免资源耗尽的风险
Executors 返回线程池的缺点如下:
- FixedThreadPool 和 SingleThreadPool 允许请求队列长度为 Integer.MAX_VALUE,可能会堆积大量请求,可能会导致内存溢出;
- CachedThreadPool 和 ScheduledThreadPool 允许创建线程数量为 Integer.MAX_VALUE,创建大量线程,可能会导致内存溢出。
Java笔试面试-Executors相关推荐
- 修作玉颜色,卖于帝王家(java笔试面试—-求职经历)
文时至今日方才起笔,不知为何,曾经在奔跑的过程中,无数次的提醒自己,等正式卖完身之后一定要写下这篇文章,来纪念过去的时日,一为警惕自身,二为温馨提示后人.但已经卖身快两个月了,还是无法真正地写下一纸半 ...
- Java笔试面试总结—try、catch、finally语句中有return 的各类情况
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 前言 之前在刷笔试题和面试的时候经常会遇到或者被问到 tr ...
- java笔试面试经典问题
java面试笔试题大汇总 JAVA相关基础知识 1.面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题 ...
- Java笔试面试(社招版)
一.并发 Java面试–线程池 Java面试–ThreadLocal Java面试–乐观锁和悲观锁 Java面试–线程的生命周期状态 Java面试–Synchronized Java面试–wait和s ...
- Java笔试面试-克隆和序列化
克隆 1.浅克隆 默认的 clone() 方法,为浅克隆,代码如下: class CloneTest {public static void main(String[] args) throws Cl ...
- Java笔试面试练习题---集合
一.单选题 1.ArrayList类的底层数据结构是( A ) A.数组结构 B.链表结构 C.哈希表结构 D.红黑树结构 解析:ArrayList底层的实现就是一个数组(固定大小),当数组长度不够用 ...
- Java笔试面试-设计模式
1.说一下设计模式?你都知道哪些? 答:设计模式总共有 23 种,总体来说可以分为三大类:创建型模式( Creational Patterns ).结构型模式( Structural Patterns ...
- Java笔试面试-JVM
1.什么是 JVM?它有什么作用? 答:JVM 是 Java Virtual Machine(Java 虚拟机)的缩写,顾名思义它是一个虚拟计算机,也是 Java 程序能够实现跨平台的基础.它的作用是 ...
- Java笔试面试-Java 分布式框架面试总结
1.什么是 ZooKeeper? 答:ZooKeeper 是一个开源的分布式应用程序协调服务,是一个典型的分布式数据一致性解决方案.设计目的是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高 ...
最新文章
- PHPUnit实践三(构建模块化的测试单元)
- 爬虫-scrapy的中间件
- 程序员常犯的五个非技术性错误
- SpringBoot集成OpenOffice实现doc文档转html
- TCP/IP 体系结构
- 《Python Cookbook 3rd》笔记(3.8):分数运算
- 信息学奥赛一本通 1031:反向输出一个三位数 | OpenJudge NOI 1.3 13
- mysql数据库复制功能配置,最详细的mysql数据库主从复制功能配置教程(docker版本)...
- 关于visio你必须要知道的一些小技巧
- iOS开发-使用Storyboard进行界面跳转及传值
- 开心网(kaixin001.com)服务器架构的一点猜想
- inline-block从入门到精通
- 模拟电子技术基础_童诗白、华成英(第五版)目录
- SPSS、 Mplus下载安装包
- python安装time模块_Python之路-Python常用模块-time模块
- 使用OpenSSL自建CA及颁发证书、吊销证书
- IPv6路由信息的序号
- 苹果手机换电池对手机有影响吗_你知道你的手机电池多久换一次吗?
- 近年来Person Re-identification论文汇总
- 数值法求解最优控制问题(四)——伪谱法