线程池 (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应用中线程池的大小决定了在任何一个时间点应用可以处理请求的并发数.如果一个系统收到的请求数超过了线程池的大小,那么超出的请求要么进入等待队列要么被拒绝.请注意, ...
随机推荐
- 转: android sdk for mac
转:http://www.cnblogs.com/yjmyzz/p/4219829.html 众所周知的原因,google的很多网站在国内无法访问,苦逼了一堆天朝程序员,下是在mac本上折腾andro ...
- 通过NAT实例实现外部访问AWS的ElastiCache资源
ElastiCache作为AWS的内存缓存组建可以说做的一点也不友好了, 你可以通过ElastiCache创建redis,memcache的实例,却不能被外部访问. 背景 人傻钱多的客户总有人傻钱多的 ...
- 各种字符编码方式详解及由来(ANSI,UNICODE,UTF-8,GB2312,GBK)
一直对字符的各种编码方式懵懵懂懂,什么ANSI UNICODE UTF-8 GB2312 GBK DBCS UCS……是不是看的很晕,假如您细细的阅读本文你一定可以清晰的理解他们.Let's go! ...
- 基于c++11新标准开发一个支持多线程高并发的网络库
背景 新的c++11标准出后,c++语法得到了非常多的扩展,比起以往不论什么时候都要灵活和高效,提高了程序编码的效率,为软件开发者节省了不少的时间. 之前我也写过基于ACE的网络server框架,但A ...
- EXCEL在使用中,jar导入问题
报错:The type org.apache.poi.ss.usermodel.Workbook cannot be resolved. It is indirectly referenced fro ...
- TP框架模板中默认值输出
TP框架模板中默认值输出 我们可以给变量输出提供默认值,例如: {$user.nickname|default="这家伙很懒,什么也没留下"} 对系统变量依然可以支持默认值输出,例 ...
- php使用curl请求数据(采集数据)
<?php $url = "http://www.baidu.com/s?wd=刘俊涛的博客"; $header = array( 'User-Agent: Mozilla/ ...
- vue 不能监测数组长度变化length的原因
由于 JavaScript 的限制,Vue 不能检测以下变动的数组: 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue 当你修改数组的长度时,例如: ...
- Patterns-Flyweight
最近在组里讨论设计模式,第一个是享元模式. 自己贴了一篇这个文章:http://www.cnblogs.com/rush/archive/2011/10/01/2197785.html 感觉这篇讲的不 ...
- iOS开发一个制作Live Photo的工具
代码地址如下:http://www.demodashi.com/demo/13339.html 1.livePhoto简介 livePhoto是iOS 9.0 之后系统相机提供的拍摄动态照片的功能,但 ...