java线程池的介绍与使用(Executor框架)
1. 先来看一下类构成
public interface Executor { //顶级接口Executor,定义了线程执行的方法 void execute(Runnable command);
}
public interface ExecutorService extends Executor {
//定义了线程池周期相关的方法
void shutdown(); //平缓的关闭:不再接受新的任务,同时等待已经提交的任务的完成(包括还未开始执行的任务) List<Runnable> shutdownNow(); //粗暴的关闭,尝试取消正在执行的任务,同时不再继续执行提交但未开始的任务 boolean isShutdown(); //查看该执行器是否关闭 boolean isTerminated(); //查询线程池是否终止 boolean awaitTermination(long timeout, TimeUnit unit) //等待线程池达到终止状态,通常在此方法后调用shutdown()达到同步关闭线程池的效果
throws InterruptedException; <T> Future<T> submit(Callable<T> task); //submit()方法用来提交带有返回值的任务 <T> Future<T> submit(Runnable task, T result); Future<?> submit(Runnable task); <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) //用来提交复数的任务
throws InterruptedException; <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException; <T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException; <T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
2. ThreadPoolExecutor为线程池的实现
public ThreadPoolExecutor(int corePoolSize, //核心线程数量,代表在空闲状态下线程池中维持的线程的数量
int maximumPoolSize, //线程池所能允许的最大线程数量
long keepAliveTime, //空闲线程的存活时间
TimeUnit unit, //时间单位
BlockingQueue<Runnable> workQueue, //用来暂时保存任务的队列
ThreadFactory threadFactory, //用来创建线程
RejectedExecutionHandler handler) { //拒绝策略,在任务无法加入到队列是发挥作用 }
3. 拒绝策略
(1)AbortPolicy: 该策略抛出RejectedExecutionException,调用者捕获异常后进行处理。
(2)DiscartPolicy:当新任务无法加入到队列中是,该策略悄悄抛弃该任务。
(3)DiscardOldestPolicy:该策略将抛弃即将要执行的任务。
(4)CallerRunsPolicy:该策略将某些任务回退到调用者。
4. 四种类型的线程池(通用线程池的方法定义在Executors类中)
当线程池的所有参数有效设置时提交任务的完整过程:查看当前线程数量是否大于corePoolSize,若小于则创建一个新的线程来执行该任务,否则将该任务加入到workQueue中;若workerQueue也满,那么查看线程的数量是否小于maximumPoolSize,若小于则创建新的线程来执行,否则执行抛弃策略。另外若线程空闲时间大于keepAliveTime,则销毁线程。
public ThreadPoolExecutor(int corePoolSize, //通用构造方法
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler); //使用默认的线程工厂和默认的拒绝策略
}
private static final RejectedExecutionHandler defaultHandler = //默认为AbortPolicy
new AbortPolicy();
(1)newFixedThreadPool :创建一个固定大小的线程池
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads, //核心数量=最大数量,keepAliveTime=0(若无以外线程将一直存在),workQueue使用LinkedBlockingQueue
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) { //另一个构造方法,可指定线程工厂
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
(2)newCachedThreadPool:创建一个可更具需要的线程池
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, //核心大小=0,最大数量不限,存活时间为60s(若长时间没有任务则该线程池为空),使用SynchronousQueue作为workeQueue
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
(3)newScheduledThreadPool:创建一个可延迟执行任务的线程池
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, //指定核心大小,不限最大数量,线程不会过期,使用DelayedWordeQueue作为workeQueue
new DelayedWorkQueue());
}
(4)newSingleThreadPool:创建一个只有一个线程的线程池
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1, //核心数量与最大数量都为1,存活时间不限,使用LinkedBlockingQueue作为workQueue
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
java线程池的介绍与使用(Executor框架)的更多相关文章
- Java 线程池的介绍以及工作原理
在什么情况下使用线程池? 1.单个任务处理的时间比较短 2.将需处理的任务的数量大 使用线程池的好处: 1. 降低资源消耗: 通过重复利用已创建的线程降低线程创建和销毁造成的消耗.2. 提高响应速度: ...
- Java 线程池详细介绍
根据摩尔定律(Moore’s law),集成电路晶体管的数量差不多每两年就会翻一倍.但是晶体管数量指数级的增长不一定会导致 CPU 性能的指数级增长.处理器制造商花了很多年来提高时钟频率和指令并行.在 ...
- Java线程池管理及分布式Hadoop调度框架搭建
平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发工程师却在这个上面吃了不少苦头. 怎么做一套简便的线程开发模 ...
- Java并发编程:Java线程池核心ThreadPoolExecutor的使用和原理分析
目录 引出线程池 Executor框架 ThreadPoolExecutor详解 构造函数 重要的变量 线程池执行流程 任务队列workQueue 任务拒绝策略 线程池的关闭 ThreadPoolEx ...
- 深入理解Java线程池:ThreadPoolExecutor
线程池介绍 在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理.如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题: 如果并发的请求数量非常多,但每个线 ...
- Java线程池使用和源码分析
1.为什么使用线程池 在多线程编程中一项很重要的功能就是执行任务,而执行任务的方式有很多种,为什么一定需要使用线程池呢?下面我们使用Socket编程处理请求的功能,分别对每种执行任务的方式进行分析. ...
- Java线程池学习总结
一 使用线程池的好处 池化技术相比大家已经屡见不鲜了,线程池.数据库连接池.Http 连接池等等都是对这个思想的应用.池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率. 线程池提供了 ...
- (转载)JAVA线程池管理
平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发攻城师却在这个上面吃了不少苦头.怎么做一套简便的线程开发模式 ...
- Java线程池的那些事
熟悉java多线程的朋友一定十分了解java的线程池,jdk中的核心实现类为java.util.concurrent.ThreadPoolExecutor.大家可能了解到它的原理,甚至看过它的源码:但 ...
随机推荐
- Mybatis入门简版(二)
一.Dao层开发的方式 以前dao层开发比较繁琐,写了接口还得写实现类,实际上用了Mybatis之后写实现类非常重复,都是重复的代码.那么此时改成另外一种简单形式. 遵循以下四个原则(名称.形参.返回 ...
- 一张图一个题帮你迅速理解RLU算法
下面是某年的软考题: 某进程页面访问序列为4,2,3,1,2,4,5,3,1,2,3,5,且开始执行时内存中没有页面,分配给该进程的物理块数是3,则采用RLU页面置换算法时的缺页率是多少? 对于这个问 ...
- [HDU5955]Guessing the Dice Roll
Problem Description There are N players playing a guessing game. Each player guesses a sequence cons ...
- go-关键字-变量
var 声明变量 const 常量的关键字, 常量不能出现只声明不赋值的情况. 名字首字母为大写的程序实体可以被任何代码包中的代码访问到. 名字首字母为小写的程序实体则只能被同一个代码包中的代 ...
- Java代码优化建议
总结日常Java开发常见优化策略,持续更新. 尽可能使用局部变量 调用方法时传递的参数以及在调用中创建的临时变量都保存在栈中,速度较快,其他变量,如静态变量.实例变量等,都在堆中创建,速度较慢.另外, ...
- java 连续数字数组分组
问题: 1. 将Lis list = Arrays.asList(1,2,3,5,8,9,10), 拆分成 [1,2,3] .[5]. [8,9,10] , 2. 再传入一个数字 9, 将匹配数字9的 ...
- redis之管道
Redis 的消息交互当我们使用客户端对 Redis 进行一次操作时,如下图所示,客户端将请求传送给服务器,服务器处理完毕后,再将响应回复给客户端.这要花费一个网络数据包来回的时间. 如果连续执行多条 ...
- java实现,使用opencv合成全景图,前端使用krpano展示
这周花三天做了一demo,算上之前的,怎么也有五天,上一篇是opencv介绍,以及定义native方法,通过本地图片路径传参,底层调用Opencv图像库合成,有兴趣的可以看看,这篇重点在于krpano ...
- 小白学 Python(11):基础数据结构(元组)
人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...
- Charles抓包工具的使用(一)
前提:charles的说明 Charles其实是一款代理服务器,通过过将自己设置成系统(电脑或者浏览器)的网络访问代理服务器,然后截取请求和请求结果达到分析抓包的目的.该软件是用Java写的,能够在W ...