线程池 (thread pool) 的类型与实现方式
在许多应用中需要频繁的创建许多生命周期很短的线程,如果用传统方法的话就会造成大量的资源了浪费,java的设计者们考虑到了这点在java中加入了线程池这个特性,它负责管理大量的线程的创建销毁等操作。
首先我们需要了解一个类:java.util.concurrent.Executors(执行器)
执行器类拥有大量的静态工厂方法用于创建线程池
| 方法 | 描述 |
| newCachedThreadPool | 必要时创建线程,处于空闲状态的线程将被保留60秒 |
| newFixedThreadPool | 拥有固定数量的线程,并且不会自动销毁空闲状态的线程 |
| newSingleThreadExecutor | 该线程池仅有一个线程,会顺序执行任务队列 |
| newScheduledThreadPool | 用于预约执行任务的固定线程池 |
| newSingleThreadScheduledExecutor | 用于预约执行任务的单线程池 |
下面我们来详细了解下这些线程池。
newCachedThreadPool:通过名称,不难看出这个方法创建出的线程池,具有数量可变,并且在需要的时候会自动创建更多的线程,并且会自动销毁线程。
newFixedThreadPool:此线程池与newCachedThreadPool构建出的线程池的主要区别是,线程池在数量上固定,如果任务数量达到上限的话,就会将多余任务加入任务队列,等线程池空出线程时即可执行,这种线程池并不会销毁空闲线程。
newSingleThreadExecutor:此方法创建出的线程池相较于其他两个线程较为特殊,此方法创建出的线程数量仅仅为1,也就是说所有除了正在执行的任务外,其余任务均在任务队列中,当线程中的任务执行完毕后,任务队列的第一个任务进入线程开始执行。
newScheduledThreadPool与 newSingleThreadScheduledExecutor:这两个方法创建出的线程池是用于预定执行的线程池,他们可以用于在初始化后延迟执行,或周期性的执行,两种线程池大体相同,唯一的区别就是可同时执行的线程数量。
当你挑选完的线程池后就需要创建以及使用线程池:
大概步骤为以下3步:
(1)调用执行器类(Executors)的静态方法来创建线程池
(2)调用线程池的submit方法提交Runnable或Callable对象
(3)当不需要添加更多的任务时,调用shutdown关闭入口
下面通过代码来逐步操作:
//创建线程池对象
ExecutorService service = Executors.newCachedThreadPool();
//创建一个用于递增输出i值的runnable对象
Runnable runnable = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 400; i++) {
System.out.println(i);
}
}
};
//调用线程池的submit方法传入runnable(传入的runnable将会自动执行)
service.submit(runnable);
service.submit(runnable);
//当不需要传入更多的任务时调用shutdown方法来关闭入口
service.shutdown();
需要注意的是如果希望直接停止线程池的一切任务是无法通过shutdown来操作的,因为shutdown仅仅是关闭了入口,但是已经加入的任务还是会继续执行的,这时我们可以调用线程池的shutdownNow方法来操作,shutdownNow的作用是用来关闭线程池的入口并且会尝试终止所有当前线程池内的任务。
//用来关闭线程池入口以及终止所有正在执行的任务
service.shutdownNow();
service的submit方法会返回一个Future<?>类型的对象,然而这是一个怎样的类型呢?让我们来看一下api中的方法摘要:

从方法摘要中可以看出该对象用于在加入线程池以后能够对此任务进行取消,查看状态等操作,如果说在加入线程池以后有可能会取消此任务的话就需要,在submit的时候就需要保存好Future对象。
//保存Future<?>
Future<?> run2 = service.submit(runnable); //用于查看是否已经执行完毕,返回类型为boolean
System.out.println(run2.isDone()); //取消任务,如果需要中断的话参数为true
run2.cancel(true);
关于线程池的简单操作大概就有这些,关于线程池的更多信息还需要深入的研究,java的最大优点是开源,也就是说想要深入学习其原理最好的方法也就是查看源码,我也会在后面补充上线程池的源码分析,希望大家支持:-D。
线程池 (thread pool) 的类型与实现方式的更多相关文章
- C#多线程实现方法——线程池(Thread Pool)
ThreadPool使用 同步机制 ThreadPool使用 需要定义waitcallback委托形式如 public delegate void WaitCallback(object stat ...
- 简易线程池Thread Pool
1. 基本思路 写了个简易的线程池,基本的思路是: 有1个调度线程,负责维护WorkItem队列.管理线程(是否要增加工作线程).调度(把工作项赋给工作线程)等 线程数量随WorkItem的量动态调整 ...
- MySQL线程池(THREAD POOL)的原理
MySQL常用(目前线上使用)的线程调度方式是one-thread-per-connection(每连接一个线程),server为每一个连接创建一个线程来服务,连接断开后,这个线程进入thread_c ...
- 使用boost实现线程池thread pool | boost thread pool example
本文首发于个人博客https://kezunlin.me/post/f241bd30/,欢迎阅读! boost thread pool example Guide boost thread pool ...
- MySQL--线程池(Thread Pool)
================================================================= 线程池技术 在MySQL社区版中,MySQL使用one-thread ...
- javade多任务处理之Executors框架(线程池)实现的内置几种方式与两种基本自定义方式
一 Executors框架(线程池) 主要是解决开发人员进行线程的有效控制,原理可以看jdk源码,主要是由java.uitl.concurrent.ThreadPoolExecutor类实现的,这里只 ...
- Spring中的定时调度(Scheduling)和线程池(Thread Pooling)
使用triggers和SchedulerFactoryBean来包装任务 我们已经创建了job details,jobs.我们同时回顾了允许你调用特定对象上某一个方法的便捷的bean. 当然我们仍需要 ...
- 基于C++11的线程池,简洁且可以带任意多的参数
咳咳.C++11 加入了线程库,从此告别了标准库不支持并发的历史.然而 c++ 对于多线程的支持还是比较低级,稍微高级一点的用法都需要自己去实现,譬如线程池.信号量等.线程池(thread pool) ...
- 如何决定Web应用的线程池大小
线程池(Thread Pool)在Web应用中线程池的大小决定了在任何一个时间点应用可以处理请求的并发数.如果一个系统收到的请求数超过了线程池的大小,那么超出的请求要么进入等待队列要么被拒绝.请注意, ...
随机推荐
- TCP为何采用三次握手来建立连接,若采用二次握手可以吗?
首先简单介绍一下TCP三次握手 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接. 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_ ...
- Spring框架学习(7)spring mvc入门
内容源自:spring mvc入门 一.spring mvc和spring的关系 spring mvc是spring框架提供的七层体系架构中的一个层,是spring框架的一部分,是spring用于处理 ...
- 向项目中添加dtd文件实现代码提示
我们在编辑代码的过程中,有代码提示的编辑工具总是受到青睐. 本文将讲解怎么在eclipse中加入dtd文件实现代码提示.myeclipse同理 选择window,选择perferences,然后拉到下 ...
- 使用ant运行testng的testng.xml并且使用testng-results.xsl美化结果
先看build.xml <?xml version="1.0" encoding="UTF-8"?> <project basedir=&qu ...
- linux 安装mysql 5.6.11
tar zxvf mysql-.tar.gz cd mysql- cmake . -DCMAKE_INSTALL_PREFIX=/home/mysql/ -DMYSQL_DATADIR=/home/m ...
- No enclosing instance of type Demo is accessible. Must qualify the allocation with an enclosing instance of type Demo (e.g. x.new A() where x is an instance of Demo).
No enclosing instance of type Demo is accessible. Must qualify the allocation with an enclosing inst ...
- 在需要隐藏navigationController控制器
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.navigationControll ...
- sass 的学习
导入scss @import "../../sass/variables.scss"; @import "../../sass/helper.scss"; @m ...
- mysql数据库中不能插入0000-00-00 00:00:00日期数据(报错Invalid datetime format: 1292 Incorrect datetime value: '0000-00-00 00:00:00')
报错信息 SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '0000-00-00 00:00:00' ...
- Atitit.二维码功能的设计实践 attilax 总结
Atitit.二维码功能的设计实践 attilax 总结 1.1. 二维码要实现的功能1 1.2. 现有二维码功能设计不足的地方(待改进)1 1.3. 二维码组件1 1.4. Java版 zxing ...