线程池 (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应用中线程池的大小决定了在任何一个时间点应用可以处理请求的并发数.如果一个系统收到的请求数超过了线程池的大小,那么超出的请求要么进入等待队列要么被拒绝.请注意, ...
随机推荐
- 怎样在Ubuntu手机应用中得到全部的环境变量值
我们在先前的例程中已经通过一些方法得到我们应用的一些环境变量值.这些值有的很实用.比方我们能够得到我们应用所仅仅能訪问的文件夹.在今天的例程中,我们来展示一种方法能够得到应用全部的环境变量.在我们的实 ...
- Linux 服务器环境启动
1.PHP 关闭php killall php-fpm php重启 /usr/local/php/sbin/php-fpm & 或者 /usr/local/php/sbin/php-fpm { ...
- http_load压力测试使用
介绍:http_load以并行复用的方式运行,用以测试web服务器的吞吐量与负载.但是它不同于大多数压力测试工具,它可以以一个单一的进程运行,一般不会把客户机搞死.还可以测试HTTPS类的网站请求. ...
- 【原创】Android自定义适配器的使用方法
比如说我们已经得到了数据,想在一个listview或者在其他的控件中显示的,并且我们显示想要自己设计样式来显示的话就要用到自定义适配器了,下面让我们结合代码讲一下具体的使用方法: 代码会有注释的哦: ...
- Windows注册表中修改CMD默认路径
一.开启注册表“win键+R键”并输入regedit 二.在注册表项 HKEY_CURRENT_USER\ Software\ Microsoft\ Command Processor 新建一个项,并 ...
- Solidworks如何隐藏零件细节,如何让零件变成一个输入
先把东西另存为IGS格式 再次打开这个IGS文件,凡是看到这个对话框都选择取消,然后确定 打开之后,还是可以看到文件结构,但是再打开每个零件都变成了输入,所以就相当于隐藏了文件细节,不知道怎么 ...
- GDB+GdbServer: ARM程序调试
arm-linux-gdb+gdbserver环境搭建以及远程调试 GDB+GdbServer: ARM程序调试 嵌入式arm linux环境中gdb+gdbserver调试 建立交叉调试环境 编译过 ...
- strtok()切割字符串函数
#include <iostream> #include <string.h> using namespace std; char *my_strtok(char *dist, ...
- ionicframework(二)
Start building with Ionic! Follow these quick steps and start building high quality mobile apps in m ...
- CentOS 6.4 编译安装 gcc 4.8.1(转)
今天在isocpp上看到“GCC 4.8.1 released, C++11 feature complete”这个消息,非常兴奋.终于有一个全面支持C++11语言特性的编译器了! 当然了,gcc仅仅 ...