1.JAVA多线程(二十一)Java多线程之SingleThreadExecutor单线程化线程池
1.1 单线程化线程池SingleThreadExecutor
SingleThreadExecutor 是只有一个线程的线程池。通过源代码查看SingleThreadExecutor实现:
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
在SingleThreadExecutor实现中:
- corePoolSize && maximumPoolSize,corePoolSize 和 maximumPoolSize 都被设置为:1。
- keepAliveTime => keepAliveTime为0,意味着多余的空闲线程会被立即终止。
- workQueue => 采用无界队列LinkedBlockingQueue作为线程池的工作队列(队列的容量为Integer.MAX_VALUE),会在循环中反复从LinkedBlockingQueue获取任务来执行。
1.2 SingleThreadExecutor使用样例
- 单线程化线程池SingleThreadExecutor特点:
- 只有一个核心线程(保证所有任务按照指定顺序在一个线程中执行,不需要处理线程同步的问题)。
- 应用场景:不适合并发但可能引起IO阻塞性及影响UI线程响应的操作,如数据库操作,文件操作等。
- SingleThreadExecutor的意义:
- 缓存线程、进行池化,可实现线程重复利用、避免重复创建和销毁所带来的性能开销。
- 当线程调度任务出现异常时,会重新创建一个线程替代掉发生异常的线程。
- 任务执行按照规定的调度规则执行。线程池通过队列形式来接收任务。再通过空闲线程来逐一取出进行任务调度。即线程池可以控制任务调度的执行顺序。
- 可制定拒绝策略。即任务队列已满时,后来任务的拒绝处理规则。
package com.yuanxw.chapter21;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
public class ScheduledThreadPoolExample {
private static Random random = new Random(System.currentTimeMillis());
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
IntStream.range(1, 10).forEach(i -> executorService.execute(ScheduledThreadPoolExample::processTask));
executorService.shutdown();
}
private static void processTask() {
try {
long start = System.currentTimeMillis();
TimeUnit.SECONDS.sleep(random.nextInt(5));
long end = System.currentTimeMillis();
System.out.println(String.format("【%s】线程执行结束,耗时【%s】秒>>>>>>>>>>>", Thread.currentThread().getName(),((end - start)/1000)));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
执行结果:
【pool-1-thread-1】线程执行结束,耗时【1】秒>>>>>>>>>>>
【pool-1-thread-1】线程执行结束,耗时【2】秒>>>>>>>>>>>
【pool-1-thread-1】线程执行结束,耗时【4】秒>>>>>>>>>>>
【pool-1-thread-1】线程执行结束,耗时【2】秒>>>>>>>>>>>
【pool-1-thread-1】线程执行结束,耗时【3】秒>>>>>>>>>>>
【pool-1-thread-1】线程执行结束,耗时【1】秒>>>>>>>>>>>
【pool-1-thread-1】线程执行结束,耗时【1】秒>>>>>>>>>>>
【pool-1-thread-1】线程执行结束,耗时【4】秒>>>>>>>>>>>
【pool-1-thread-1】线程执行结束,耗时【3】秒>>>>>>>>>>>
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200201183104201.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3l1YW5feHc=,size_16,color_FFFFFF,t_70)
SingleThreadExecutor 的 execute()方法的执行示意图(该图片来源:《Java 并发编程的艺术》):
- 如果当前运行的线程数少于 corePoolSize,则创建一个新的线程执行任务;
- 当前线程池中有一个运行的线程后,将任务加入 LinkedBlockingQueue
- 线程执行完当前的任务后,会在循环中反复从 LinkedBlockingQueue 中获取任务来执行;
– 以上为《JAVA多线程(二十一)Java多线程之SingleThreadExecutor单线程化线程池》,如有不当之处请指出,我后续逐步完善更正,大家共同提高。谢谢大家对我的关注。
——厚积薄发(yuanxw)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)