Java线程池核心原理剖析
在系统开发时,我们经常会遇到“池”的概念。使用池一种以空间换时间的做法,通常在内存中事先保存一系列整装待命的对象,以供后期供其他对象随时调用。常见的池有:数据库连接池,socket连接池,线程池等。今天我们就来看一下线程池的概念。
◆
Executor
◆
JDK为我们提供了一套Executor框架来方便我们来管理和使用线程池。
打开java.util.concurrent.Executors类,我们可以发现JDK为我们提供了那么多的方法来帮助我们高效快捷的创建线程池:
1 |
public static ExecutorService newFixedThreadPool(int nThreads);//创建一个固定数目的、可重用的线程池 |
上方简单列举了几个Executor框架为我们提供的创建线程池的方法,这些线程池拥有各种各样的功能,我想当你刚刚开始使用线程的时候google如何使用线程池的时候大部分文章都是教你如何使用上方的一些方法创建一个线程池。但是如果你去查看他们的源码就会发现他们最后构造的时候都调用了同一个构造方法。(除了newWorkStealingPool之外,这个我们在下篇文章再讨论)
1 |
ThreadPoolExecutor(int corePoolSize,//线程池线程数量 |
上方的4个参数我想你看到了就会明白了,现在我们着重来讲一下下面的三个参数。
◆
WorkQueue
◆
参数workQueue是用来存放已提交但还未执行的任务,JDK为我们提供了一下实现:
直接提交队列SynchronousQueue
1 |
当新任务过来的时候它是这样处理的: |
因此使用这个队列时一定要设置很大的maximumPoolSize
有界的任务队列ArrayBlockingQueue
1 |
if(当前线程数<corePoolSize){
|
无界的任务队列LinkedBlockingDeque
1 |
if(当前线程数<corePoolSize){
|
◆
线程工厂
◆
第六个参数threadFactory是为线程池中创建线程的,我们使用Executor框架创建的线程就是有threadFactory提供的。我们看一下JDK提供的默认的threadFactory:
1 |
static class DefaultThreadFactory implements ThreadFactory {
|
重点关注一下其中的newThread方法,看到这个我想你就明白了为什么你使用线程池创建出来的线程打印的时候名字的来源,还有是否是守护线程和优先级等属性的来源了。
◆
拒绝策略
◆
看到刚刚的几种任务队列我们发现当任务过多时是需要指定拒绝策略来进行拒绝呢,那么JDK又为我们提供了哪些拒绝策略呢。
1 |
AbortPolicy直接抛出异常。 |
◆
线程池的扩展
◆
ThreadPoolExecutor不仅仅能够创建各种各样的线程来帮助我们实行功能,它还预留了三个接口来供我们进行扩展。
在runWorker方法中调用线程进行执行之前调用了beforeExecute方法,执行之后调用了afterExecute()方法
1 |
final void runWorker(Worker w) {
|
这两个方法在ThreadPoolExecutor类中是没有实现的,我们想要监控线程运行前后的数据就可以通过继承ThreadPoolExecutor类来实现这个扩展。
另外还有一个terminated()方法是在整个线程池退出的时候调用的,我们这里一并扩展。
public class ThreadPoolExecutorDemo extends ThreadPoolExecutor {
//注意这里因为ThreadPoolExecutor没有无参的构造,所以还需要重写一下构造方法。
//这里限于篇幅就不贴了
@Override
protected void afterExecute(Runnable r, Throwable t) {
System.out.println(Thread.currentThread().getId()+"执行完成");
}
@Override
protected void terminated() {
System.out.println("线程池退出");
}
}
//使用这个demo就可以验证我们扩展的结果了。
public class ThreadPoolDemo {
static class ThreadDemo extends Thread {
@Override
public void run() {
System.out.println(System.currentTimeMillis() + ":Thread ID is:" + Thread.currentThread().getId());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
ThreadPoolExecutorDemo threadPoolExecutorDemo= new ThreadPoolExecutorDemo(5,5,0,TimeUnit.SECONDS,new LinkedBlockingDeque<Runnable>());
ThreadDemo threadDemo = new ThreadDemo();
for (int i = 0; i < 20; i++) {
threadPoolExecutorDemo.submit(threadDemo);
}
threadPoolExecutorDemo.shutdown();
}
}
本文所有源码:https://github.com/shiyujun/syj-study-demo
Java线程池核心原理剖析的更多相关文章
- Java 线程池的原理与实现 (转)
最近在学习线程池.内存控制等关于提高程序运行性能方面的编程技术,在网上看到有一哥们写得不错,故和大家一起分享. [分享]Java 线程池的原理与实现 这几天主要是狂看源程序,在弥补了一些以前知 ...
- Java线程池实现原理及其在美团业务中的实践
本文转载自Java线程池实现原理及其在美团业务中的实践 导语 随着计算机行业的飞速发展,摩尔定律逐渐失效,多核CPU成为主流.使用多线程并行计算逐渐成为开发人员提升服务器性能的基本武器.J.U.C提供 ...
- 我眼中的java线程池实现原理
最近在看java线程池实现方面的源码,在此做个小结,因为网上关于线程池源码分析的博客挺多的,我也不打算重复造轮子啦,仅仅用纯语言描述的方式做做总结啦! 个人认为要想理解清楚java线程池实现原理,明白 ...
- Java线程池的原理及几类线程池的介绍
刚刚研究了一下线程池,如果有不足之处,请大家不吝赐教,大家共同学习.共同交流. 在什么情况下使用线程池? 单个任务处理的时间比较短 将需处理的任务的数量大 使用线程池的好处: 减少在创建和销毁线程上所 ...
- 并发编程(十二)—— Java 线程池 实现原理与源码深度解析 之 submit 方法 (二)
在上一篇<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中提到了线程池ThreadPoolExecutor的原理以及它的execute方法.这篇文章是接着上一篇文章 ...
- 11 java 线程池 实现原理
一 关键类的实现 1 ThreadPoolExecutor类 java.uitl.concurrent.ThreadPoolExecutor类是线程池中最核心的一个类,因此如果要透彻地了解Java中的 ...
- Java 线程池(ThreadPoolExecutor)原理分析与使用
在我们的开发中"池"的概念并不罕见,有数据库连接池.线程池.对象池.常量池等等.下面我们主要针对线程池来一步一步揭开线程池的面纱. 使用线程池的好处 1.降低资源消耗 可以重复利用 ...
- Java 线程池(ThreadPoolExecutor)原理解析
在我们的开发中“池”的概念并不罕见,有数据库连接池.线程池.对象池.常量池等等.下面我们主要针对线程池来一步一步揭开线程池的面纱. 有关java线程技术文章还可以推荐阅读:<关于java多线程w ...
- Java线程池实现原理与技术(ThreadPoolExecutor、Executors)
本文将通过实现一个简易的线程池理解线程池的原理,以及介绍JDK中自带的线程池ThreadPoolExecutor和Executor框架. 1.无限制线程的缺陷 多线程的软件设计方法确实可以最大限度地发 ...
随机推荐
- Linux小知识收集(不断更新)
一.说明 以下知识点都来自网络收集,只是给自己记录以免下次同样的问题的时候会忘记,如果知道出处,我都会进行标注,如果侵权的话,请邮件通知我,我会及时删除的 二.知识点 1.将centos的源修改为阿里 ...
- (详细)华为P8 GRA-UL00的Usb调试模式在哪里开启的方法
经常我们使用Pc通过数据线连接上安卓手机的时候,如果手机没有开启usb开发者调试模式,Pc则没能够成功检测到我们的手机,有时候我们使用的一些功能较强的应用软件好比之前我们使用的一个应用软件引号精灵,老 ...
- 远程链接mysql
一. 设置账户密码 1. 创建用户:CREATE USER 'jiang'@'%' IDENTIFIED BY '1'; //%表示所有端口 2. 授予权限: GRANT ALL PRIVILEGES ...
- Bootstrap-datepicker3官方文档中文翻译---I18N/国际化(原文链接 http://bootstrap-datepicker.readthedocs.io/en/latest/index.html)
I18N/国际化 这个插件支持月份和星期名以及weekStart选项的国际化.默认是英语(“en”); 其他有效的译本语言在 js/locales/ 目录中, 只需在插件后包含您想要的地区. 想要添加 ...
- aliyun install Discourse log
apt update apt install wget wget -qO- https://get.docker.com/ | sh vim /etc/default/docker DOCKER_OP ...
- 编译phoneix源码,整合Hbase
Hbase版本:1.2.0-cdh5.14.0 1):下载phoneix源码 链接:https://pan.baidu.com/s/1uryK_jLEekdXV04DRc3axg 密码:bkqg 2) ...
- Spring常用注解总结
转载自:https://www.cnblogs.com/xiaoxi/p/5935009.html 传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点 ...
- java位移运算符3 转
https://www.cnblogs.com/winsker/p/6728672.html 移位运算符操作的对象就是二进制的位,可以单独用移位运算符来处理int型整数. 理解java移位运算符 运算 ...
- Win10 Store 还原
Get-AppxPackage -allusers | Select Name, PackageFullName Add-appxpackage -register "C:\Program ...
- 【转】window.onerror跨域问题
What the heck is "Script error"? Ben Vinegar/ May 17, 2016 If you’ve done any work with th ...