java 线程池第一篇 之 ThreadPoolExcutor
一:什么是线程池?
java 线程池是将大量的线程集中管理的类,包括对线程的创建,资源的管理,线程生命周期的管理。当系统中存在大量的异步任务的时候就考虑使用java线程池管理所有的线程。减少系统资源的开销。
二:线程池工厂类有多少种?
java1.8 的官方文档提供了三种线程池工厂类,每种线程池工厂类型对应不同线程管理方式(策略)。
newCachedThreadPool(自动废弃回收):
当有可用的空闲线程,优先使用空闲线程,当没有可用的空闲线程的时候就创建新的线程。空闲线程超过60s没有被使用,将会关闭并从线程缓冲区中删除。这种设计的好处就是当并发高峰期过了之后,大量的空闲线程就会被回收,节省系统资源。
newFixedhreadPool(固定线程池大小):
首先创建一个固定线程大小的线程池,将所有的线程激活,创建一个无界任务队列存放所有的任务,当线程池中有可用的空闲线程,队列的任务就会被消费,当线程池中没有空闲线程,任务队列中的任务就等待,直到有线程被空出。当某个线程应为运行期间被异常关闭,其他的线程将会接替其运行后来的任务。这种线程池的好处就是不会再高峰的时候一直创建新的线程。线程空闲的时候也不会被销毁。除非程序员手动明确的调用关闭线程池的方法。
newSingleThreadExecutor(单工作线程): 任何时候都只有一个线程被激活处理无界任务队列,当运行中的线程因为异常而关闭的时候,新的线程将被创建,这样的线程池将保证所有的任务顺序执行。
三:测试线程池demo
package test.thread.threadPool; import org.junit.Test; import java.util.concurrent.*; /**
* 线程池
*/
public class ThreadPool { /**
* @version 经过测 试发现Junit的@Test注解不支持多线程,当单元测试的线程关闭之后,就会关闭所有的线程
* @see @Test 注解会调用System.exit(0); 方法退出程序异步线程无法执行
*/
public static void main(String[] args){
/*
* 创建一个线程的实例
* 核心线程大小5
* 最大线程大小10
* 线程没有处理任务的时候存活的时间
* 创建一个数组阻塞队列(队列的长度为5)
* */
ThreadPoolExecutor executor = new ThreadPoolExecutor(5,10,8000,
TimeUnit.MILLISECONDS, new LinkedBlockingDeque<Runnable>());
for(int i=0;i<15;i++){
MyTask myTask = new MyTask(executor);
//两种方法调用将任务加入到阻塞队列中submit(Runnable) 和 excute(Runnable) 方法
executor.submit(myTask); //线程执行完毕返回一个future对象
}
} }
class MyTask implements Runnable { private ThreadPoolExecutor executor; public MyTask(ThreadPoolExecutor ex){
this.executor=ex;
} @Override
public void run() {
synchronized (executor) { //加锁监视器的目的是应为多个线程修改数据,调用get方法可能获取数不对
System.out.println("线程-" + Thread.currentThread().getId() + ":正在执行task ");
try {
//线程休眠三秒更直观的查看效果
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程池中核心线程数目:" + executor.getPoolSize() + ",队列中等待执行的任务数目:" +
executor.getQueue().size() + ",已执行完成的任务数目:" + executor.getCompletedTaskCount());
}
}
}
源码解析:ThreadPoolExecutor 是线程池的核心类,他有四个构造函数,分别是为了选择不同的线程工厂策略,异常处理,任务管理。
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler); //默认线程工厂和处理器
}
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory)
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
corePoolSzie:这个参数是线程池的核心参数,表示当前线程数小于corePoolSize的时候,线程池每接收一个新的任务将创建一个新的线程,即使有空闲的线程也不会复用。
maximumPooSize:最大线程池拥有的线程数,当线程池中的线程数大于corePoolSize的时候,先复用corePoolSize中的空闲线程,当没有空闲线程的时候就创建新的线程,但是线程的总数不会超过maximunPoolSize.
keepAliveTime:非核心线程能存活的最大时间。当线程数超过corePoolSize的时候,当有空闲的线程时间超过keepAliveTime将会被回收。
unit:时间的单位,用TimeUnits这个类的类属性。属性包含NANOSECONDS,MICROSECONDS,MILLISECONDS,SECONDS,MINUTES,HOUR,DAYS
workQueue:线程池将要消费的任务,这个任务的类型必须是线程,要继承Runnable 的接口,就这是为什么要叫线程池,对于阻塞队列,一般会有ArrayBlockQque,LinkedBlockQueue,synchronousQueue 三种。
defaultHandlerExecutor:默认的拒绝策略,当线程池关闭的时候,新的任务将被拒绝,并且展现不同的处理策略
注意:excutor.shutDown(); 方法是将线程池关闭,已经在线程池中的任务将会继续执行,没有被接受的任务将不会在处理。
当线程池的队列用的ArrayBlockQque 的时候,若线程池中的所有线程都被用完,并且还有任务进入队里将会抛出RejectedExecutionException
四:方法解析
ThreadExcutor 类最高继承接口Executor,Executor 这个接口只生命了一个方法:execute(Runnable commond)
类uml图
Executor 接口:execute(Runnable commond) 方法是调用线程的核心方法
ExecutorService 接口:提供了管理异步线程的方法。
shutdown() :将当前正在执行的异步任务继续执行,不再接受新的任务进入线程池。
shutdownNow():将当前正执行的线程关闭,不在接受新的任务进入线程池。
submit():将任务提交到线程池中,并且会返回Future对象。底层调用的是Runnable 的run()方法或者是callable 的call()方法
AbstractExecutorService: 实现了submit 方法,提供线程返回值,但是这种线程的执行是直接的调用的run() 方法,导致最后线程池所有的线程都是顺序执行,并不是异步的
ThreadExecutor 提供了创建线程池的构造函数,以及拒绝策略,还有各种监控线程执行状态的方法。
java 线程池第一篇 之 ThreadPoolExcutor的更多相关文章
- 新鲜出炉!JAVA线程池精华篇深度讲解,看完你还怕面试被问到吗?
前言 前两天趁着假期在整理粉丝私信的时候看到一个粉丝朋友的私信跟我说自己现在正在复习准备面试,自己在复习到线程池这一块的时候有点卡壳,总感觉自己差了点什么.想要我帮他指导一下.这不趁着假期我也有时间我 ...
- 并发包的线程池第一篇--ThreadPoolExecutor执行逻辑
学习这个很长时间了一直没有去做个总结,现在大致总结一下并发包的线程池. 首先,任何代码都是解决问题的,线程池解决什么问题? 如果我们不用线程池,每次需要跑一个线程的时候自己new一个,会导致几个问题: ...
- Java线程入门第一篇
Java线程的状态有6种 1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法. 2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running) ...
- 深入浅出Java线程池:源码篇
前言 在上一篇文章深入浅出Java线程池:理论篇中,已经介绍了什么是线程池以及基本的使用.(本来写作的思路是使用篇,但经网友建议后,感觉改为理论篇会更加合适).本文则深入线程池的源码,主要是介绍Thr ...
- Java线程池详解,看这篇就够了!
构造一个线程池为什么需要几个参数?如果避免线程池出现OOM?Runnable和Callable的区别是什么?本文将对这些问题一一解答,同时还将给出使用线程池的常见场景和代码片段. 基础知识 Execu ...
- Java线程池的了解使用—筑基篇
前言 Java中的线程池是一个很重要的概念,它的应用场景十分广泛,可以被广泛的用于高并发的处理场景.J.U.C提供的线程池:ThreadPoolExecutor类,可以帮助我们管理线程并方便地并行执行 ...
- Java线程池与java.util.concurrent
Java(Android)线程池 介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行 ...
- java线程池的使用与详解
java线程池的使用与详解 [转载]本文转载自两篇博文: 1.Java并发编程:线程池的使用:http://www.cnblogs.com/dolphin0520/p/3932921.html ...
- 并发编程(十二)—— Java 线程池 实现原理与源码深度解析 之 submit 方法 (二)
在上一篇<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中提到了线程池ThreadPoolExecutor的原理以及它的execute方法.这篇文章是接着上一篇文章 ...
随机推荐
- Android AR场景拍照技术实现(有关键源代码)
ARVR技术交流群:129340649 欢迎增加. AR场景往往给别人留下的印象深刻,假设模型做的炫丽一点,效果将会更好. 那么怎样保存这一美好的情景呢?这篇文章将教你怎样实现AR场景的拍摄以及永久保 ...
- autofac如何注册静态方法里的接口对象
标题可能是不准确的,因为我不知道如何描述.不知道的原因,是对依赖注入一知半解. Autofac可以自动注册对象实例到接口,人所尽知.而在asp.net mvc中,这个实例化的工作,通常在每个控制器的构 ...
- Educational Codeforces Round 17 D. Maximum path DP
题目链接:http://codeforces.com/contest/762/problem/D 多多分析状态:这个很明了 #include<bits/stdc++.h> using na ...
- 使用ADO.NET对SQL Server数据库进行訪问
在上一篇博客中我们给大家简介了一下VB.NET语言的一些情况,至于理论知识的学习我们能够利用VB的知识体系为基础.再将面向对象程序设计语言的知识进行融合便可进行编程实战. 假设我们须要訪问一个企业关系 ...
- [Usaco2017 Feb]Why Did the Cow Cross the RoadII
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=4993 [算法] 动态规划 转移类似于求LCS [代码] #include<bi ...
- 堆与栈(JAVA)——以String str="abc"的深度含义解释
栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的 ...
- Linux - 常用命令索引
文件和目录操作 pwd - 显示当前所在的位置 cd - 切换目录 文件过滤及内容编辑 ... 文本处理三剑客 ... 系统信息查询与搜索文件 ... 文件备份与压缩 ... 用户管理与信息查询 .. ...
- ssi,服务器端包含,<include file="">
一.什么是SSI ssi,全称Server Side Include,中文名,服务器端包含. SSI (Server Side Includes)是HTML页面中的指令,在页面被提供时由服务器进行运算 ...
- bzoj 4606: [Apio2008]DNA【dp】
写题五分钟读题两小时系列-- 看懂题的话不算难,然而我去看了大佬的blog才看懂题-- 题目大意是:一个原字符串,其中有一种通配符,合法串的定义是这个串(不含通配符))可以匹配原串并且这个串最多分成k ...
- 初学者的疑惑,到底什么是javaBean?
JavaBeans是Java中一种特殊的类,可以将多个对象封装到一个对象(bean)中.特点是可序列化,提供无参构造器,提供getter方法和setter方法访问对象的属性.名称中的"Bea ...