Java并发机制(7)--线程池ThreadPoolExecutor的使用
Java并发编程:线程池的使用
整理自:博客园-海子-http://www.cnblogs.com/dolphin0520/p/3932921.html
1、什么是线程池,为什么要使用线程池:
1.1、线程池是线程的集合,里面的线程可以重复使用:java在java.util.concurrent下提供了一个Executor接口及其实现,用于创建管理线程池;线程池是指在初始化一个多线程应用时创建一个线程集合,再需要执行新的任务时,重复使用这些线程,而不是去创建新线程。
1.2、(1)缩短线程的创建和销毁时间,提高程序的性能;
(2)根据系统的承受能力,调整线程池中工作线程的数目,防止开销过大造成宕机。
1.3、常用的几种线程池:java doc不建议我么直接使用ThreadPoolExecutor创建线程池,而是使用Executors的静态方法创建;
(1):Executors.newCachedThreadPool(); 可缓存线程池,可根据需要创建新线程,终止超过60秒空闲的线程。
(2):Executors.newSingleThreadExecutor(); 只有一个单线程,串行执行所有任务。
(3):Executors.newFixedThreadPool(
int
):固定线程数线程池,达到固定数量后不新建也不消除。
2、Java中的ThreadPoolExecutor类
2.1、主要参数:corePoolSize:核心池的大小;maximumPoolSize:最大线程数;keepAliveTime:无任务时线程保持多久会终止;unit:KeepAliveTime的时间单位;workQueue:阻塞队列,存储等待执行的任务;threadFactory线程工厂用来创建线程;hander:拒绝处理任务时的策略; 2.2、继承关系:ThreadPoolExecutor继承自AbstractExecutorService实现了ExecutorService接口继承了Executor接口; 2.3、ThreadPoolExecutor中的主要方法:
execute():提交任务
submit():提交任务并返回结果Future;
shutdown()shutdownNow():关闭线程池;
2.4、线程池的状态:
Running(创建时运行)->ShutDown(调用shutdown)/Stop(调用ShutDownNow状态)->Terminated(上一状态,所有线程已销毁,缓存队列已经清空);
2.5、任务的执行:
【1】线程池有线程(<corePoolSize)空闲,来任务给空闲线程;
【2】CorePoolSize已满,尝试将任务进入等待队列,若不成功(workQueue已满)尝试新建线程去执行该任务;
【3】当前线程池数量达到maximumPoolSize,再来的任务采取拒绝策略(hander)处理任务;
【4】线程数量超过maximumPoolSize时,若空闲线程的空闲时间超过了keepAliveTime,线程被终止,知道线程数量不大于CorePoolSize;如果允许核心线程设置KeepAliveTime,那么核心线程空闲一定时间后也会被终止。
2.6、任务缓存队列workQueue及其排队策略:
workQueue用来存放等待执行的任务,类型为BlockingQueue<Runnable>通常取一下三种类型:
(1):ArrayBlockingQueue:基于数组的,先进先出,需要指名大小;
(2):LinkedBlockingQueue:基于链表的先进先出队列,默认大小Integer.MAX_VALUE
(3):synchronousQueue:不保存任务,直接开启新线程去执行任务。
2.7、任务拒绝策略:线程池任务缓存队列workQueue以满,且线程池内线程数目达到maximumPoolSize:
(1):ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
(2):ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
(3):ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
(4):ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
2.8、关闭:shutdown()等待所有任务结束,且不接受新任务;shutdownNow():立即关闭,尝试打断正在执行的任务,清空缓存队列。
2.9、线程池容量动态调整:setCorePoolSize()和setMaximumPoolSize();
3、:java中ThreadPoolExecutor的使用实例;
public class Test {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(5)); for(int i=0;i<15;i++){
MyTask myTask = new MyTask(i);
executor.execute(myTask);
System.out.println("线程池中线程数目:"+executor.getPoolSize()+",队列中等待执行的任务数目:"+
executor.getQueue().size()+",已执行玩别的任务数目:"+executor.getCompletedTaskCount());
}
executor.shutdown();
}
}
class MyTask implements Runnable {
private int taskNum; public MyTask(int num) {
this.taskNum = num;
} @Override
public void run() {
System.out.println("正在执行task "+taskNum);
try {
Thread.currentThread().sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("task "+taskNum+"执行完毕");
}
}
结果:
正在执行task 0
线程池中线程数目:1,队列中等待执行的任务数目:0,已执行玩别的任务数目:0
线程池中线程数目:2,队列中等待执行的任务数目:0,已执行玩别的任务数目:0
正在执行task 1
线程池中线程数目:3,队列中等待执行的任务数目:0,已执行玩别的任务数目:0
正在执行task 2
线程池中线程数目:......
4、java.util.concurrent.ThreadPoolExecutor的继承关系
Java并发机制(7)--线程池ThreadPoolExecutor的使用的更多相关文章
- Java并发编程:线程池ThreadPoolExecutor
多线程的程序的确能发挥多核处理器的性能.虽然与进程相比,线程轻量化了很多,但是其创建和关闭同样需要花费时间.而且线程多了以后,也会抢占内存资源.如果不对线程加以管理的话,是一个非常大的隐患.而线程池的 ...
- Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- Java并发编程:线程池的使用(转)
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- (转)Java并发编程:线程池的使用
背景:线程池在面试时候经常遇到,反复出现的问题就是理解不深入,不能做到游刃有余.所以这篇博客是要深入总结线程池的使用. ThreadPoolExecutor的继承关系 线程池的原理 1.线程池状态(4 ...
- Java并发编程:线程池的使用(转载)
转载自:https://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...
- Java并发编程:线程池的使用(转载)
文章出处:http://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...
- [转]Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- 【转】Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- 13、Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- [转] 引用 Java自带的线程池ThreadPoolExecutor详细介绍说明和实例应用
PS: Spring ThreadPoolTaskExecutor vs Java Executorservice cachedthreadpool 引用 [轰隆隆] 的 Java自带的线程池Thre ...
随机推荐
- Spring Boot 启动特别慢的问题
Q:debug模式下代码编译没有问题,本来10 ms左右可以启动的项目,却耗时了3000多ms,why? A:删除项目中的断点,留几个要用的就行. 至于怎么一键删除所有断点,请自行搜索! 一度以为我的 ...
- NET命令入侵实例
实验目的 了解NET入侵的过程 掌握NET命令的使用方法和它的参数搭配 实验内容 NET命令的使用方法和它的参数搭配 实验环境描述 XP作为客户端,Windows server 2003作为远程服务器 ...
- 你的程序员女孩「GitHub 热点速览 v.22.09」
本周最火的项目要数上周推荐的开源项目 How to Cook,火到一周涨了 18k+ star,但网友对它的定量烹饪方法褒贬不一.在本人看来,烹饪本就是一门"玄学",萝卜青菜各有所 ...
- 【C# IO 操作 】内存之RAM、SRAM、DRAM、ROM、FLASH、SDRAM、DDR*
内存 内存(Memory)指的是内存存储器,又称为主存,是CPU用来直接寻址和存储的空间,它相当于一座桥梁,用以负责诸如硬盘.主板.显卡等硬件上的数据与处理器之间数据交换处理,我们可以把内存看作数据缓 ...
- C# StopWatch程序性能_时间计时器
StopWatch 时间计数器简介: Stopwatch 可以测量一个时间间隔的运行时间,也可以测量多个时间间隔的总运行时间.一般用来测量代码执行所用的时间或者计算性能数据,在优化代码性能上可以使用S ...
- WPF中RichTextBox中添加文字的两种方法
RichTextBox控件不同于TextBox控件,后者可以直接通过其Text属性绑定或者在后台动态添加文字. (一)使用数据绑定 <RichTextBox FontSize="12& ...
- Winform实现客户端的自动更新
话不多说,直接上干货.当然也希望各位前辈多多指导. 自动更新客户端的设计原理图 请花两分钟时间,仔细阅读下面这张图,明白客户端自动升级的原理. 自动更新的效果图 1. ...
- 基于COCO数据集验证的目标检测算法天梯排行榜
基于COCO数据集验证的目标检测算法天梯排行榜 AP50 Rank Model box AP AP50 Paper Code Result Year Tags 1 SwinV2-G (HTC++) 6 ...
- (第一章第四部分)TensorFlow框架之张量
系列博客链接: (一)TensorFlow框架介绍:https://www.cnblogs.com/kongweisi/p/11038395.html (二)TensorFlow框架之图与Tensor ...
- 小白上手Linux系统安装jdk教程
1.查看是否有预装jdk及jdk版本: rpm -qa|grep jdk 如果有则卸载安装:rpm -e --nodeps jdk-1.7.0_79-fcs.x86_64 2.先将linux版的jdk ...