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.无限制线程的缺陷 多线程的软件设计方法确实可以最大限度地发 ...
随机推荐
- OpenStack--Rabbitmq组件消息队列
概念 队列 MQ 全称为Message Queue,消息队列( MQ ) 是一种应用程序的通信方法.应用程序通过读写入列队的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们. 消息传递指的是 ...
- Bootstrap-datepicker3官方文档中文翻译---Markup/标记(原文链接 http://bootstrap-datepicker.readthedocs.io/en/latest/index.html)
Markup/标记 下面是已经支持的标签的例子.这些标签本身不会提供DatePicker控件:你需要在标签上实例化Datepicker. input/输入框 最简单的例子: input获得焦点 (使用 ...
- Blend 打开psd文件
1.创建完项目后->文件->导入ps文件->选择psd文件
- JAVA操作证书
一.生成证书工具keytool Java自带的工具keytool可以用来生成密钥证书,也可以查看或删除证书库里的证书.无论是windows还是Linux系统,这个工具都会出现在jdk安装目录的bin文 ...
- 在SOUI中使用布局模板
概要 注意:布局模板是SOUI 2.8.0.4 新增加的功能.之前版本不支持. SOUI的listview等一系统控件支持通过模板来创建列表项,这里要说的模板不是指listview中的使用的列表项模板 ...
- java精确计算、精确计算工具类
java精确计算 package org.aisino.erp.webservice.dzfp.util; import java.math.BigDecimal; public class Math ...
- 防御xss 大致理解
前端 发送留言内容 包含 js 代码 后台 管理员 查看 留言 代码被执行 拿到cookie 成功登陆 解决办法 对录入 进行相关的过滤处理 其他解决方法 正在学习中
- 在NSMutableArray中添加空元素:NSNull类的使用
有时需要将一些表示“空”的对象添加到array中.NSNull类正是基于这样的目的产生的.用NSNull表示一个占位符时,语句表达如下: [array addObject:[NSNull null]] ...
- Adams命令
1. FIND_MACRO_FROM_COMMAND(STRING): 通过宏命令找到宏所在位置 2. DEFAULT_GROUND($_topgui.model): 获取默认地面Part 3. DB ...
- teamviewer quicksupport 插件(下载)
teamviewer quicksupport 插件(下载) teamviewer是一款远程控制软件(免费,比较好的); teamviewer quicksupport是一款支持手机可以被远程控制软件 ...