java自定义线程_Java自定义线程池详解

自定义线程池的核心:ThreadPoolExecutor

为了更好的控制多线程,JDK提供了一套线程框架Executor,帮助开发人员有效的进行线程控制,其中在java.util.concurrent包下,是JDK并发包的核心,比如我们熟知的Executors。Executors扮演着线程工厂的角色,我们通过它可以创建特定功能的线程池,而这些线程池背后的就是:ThreadPoolExecutor。那么下面我们来具体分析下它。

构造ThreadPoolExecutor

e71c00c6a957f6641af0ebd93aa36563.pngpublic ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue,

ThreadFactory threadFactory,

RejectedExecutionHandler handler) {

if (corePoolSize 

maximumPoolSize <= 0 ||

maximumPoolSize 

keepAliveTime 

throw new IllegalArgumentException();

if (workQueue == null || threadFactory == null || handler == null)

throw new NullPointerException();

this.corePoolSize = corePoolSize;

this.maximumPoolSize = maximumPoolSize;

this.workQueue = workQueue;

this.keepAliveTime = unit.toNanos(keepAliveTime);

this.threadFactory = threadFactory;

this.handler = handler;

}

corePoolSize:核心线程数

maximumPoolSize:最大线程数

keepAliveTime + unit:线程回收时间

workQueue:任务较多时暂存到队列

threadFactory:执行程序创建新线程时使用的工厂

handler:超出线程池容量以及队列长度后拒绝任务的策略

有界队列 or ×××队列

我们知道对于BlockingQueue而言,有典型的有界队列ArrayBlockingQueue以及LinkedBlockingQueue这种×××队列,那么对于线程池而言,workQueue采用有界队列、×××队列会产生什么影响呢?如果采用×××队列,那么会存在拒绝策略吗?显然不会,因为容量是无限的,比如没有预定义容量的LinkedBlockingQueue。比如,在某个时段突发很多请求,那么采用×××队列就保证了增长的可能性,而不是拒绝。如果采用有界队列,相比×××队列而言,有助于防止资源耗尽,在实际中我们经常在拒绝策略中记录log,然后通过定时任务的方式进行处理。

cce9d725d959f295369694afe754b938.png

接着上面的分析思路,想一想采用有界队列、×××队列中线程池的大小,这里涉及到一个问题,那就是任务增长时,是先增长至maximumPoolSize,还是先暂存到队列中的问题?

corePoolSize and maximumPoolSize

一个是核心线程数,一个是最大线程数,怎么理解呢?在线程池初始化阶段,是否已经初始化好corePoolSize个线程呢?大量任务来了后,线程池中的线程怎么变化?任务完成处理后,线程池又是如何回收的,回收到什么程度?

下面先来看一个线程池处理流程图:

f9b014082753d8fc1cb8e095de0ac1e3.png

简单一句话:提交任务,线程池中的线程数可以增长至corePoolSize,之后继续提交任务将暂存至队列中,如果队列满,则看是否能继续增长线程数至maximumPoolSize,超出后将进行拒绝策略处理。显然,如果采用×××队列,那么maximumPoolSize将失效,线程池中的线程最多就是corePoolSize个线程工作。

从这里我们也可以看出,在需要判断是否corePoolSize是否已经达到,需要锁的介入,因此我们应尽量让线程启动后线程池的大小就处于>=corePoolSize个数,提前预热。

keepAliveTime + unit

这里涉及到线程池回收线程。简单来说,就是采用有界队列,导致corePoolSize满,队列满,不得已线程池的线程增长至maximumPoolSize,那么任务处理完毕后,线程池中多出corePoolSize的部分理应回收,那么等待多长时间,多长时间没有任务后在进行回收的问题就是由上面的参数决定。

Executors创建线程池实例分析

固定线程池

d07435e606f11ae3b7ee9ad0ae43214f.png

特点:

×××队列,导致keepAliveTime/unit/maximumPoolSize失效,不存在拒绝;

随着任务的增长,线程数将固定在corePoolSize。

缓存线程池

212071d0893bb49f0f4a82113f428f98.png

特点:

一个比较特殊的队列:SynchronousQueue,没有容量可言,提交任务就意味着一直阻塞等待任务的线程立刻得到任务进行执行。说白了,就是不要暂存到队列中,任务直接提交给线程进行执行。由于任务无法暂存,因此缓存线程池会根据任务的实际情况,进行线程池的增长,直至maximumPoolSize(Integer.MAX_VALUE)。

注意到keepAliveTime被设置成了60S,意思就是说如果任务来了很多,缓存线程池创建了不少线程来对付它们,任务处理的差不多了,那么等待60S后,还没有任务需要处理,那么进行线程回收处理。

单线程池

acddf2116648ecc5ee2b1b8f1f80738a.png

特点:

×××队列+核心、最大线程数都是1。

打个简单比喻,任务来了,不管多少,那么有序的放着,工人只有一个,那就按照顺序处理任务就是了。就是一个单线程顺序处理任务的情况。

定时线程池

74bfb637493666e74403842b99b2073c.png

45eb6d9a7c3d6a8d4f77f491260c99c4.png

特点:

利用延时队列DelayedQueue(×××队列),完成线程池实现定时以及周期性执行任务的需要。

拒绝策略

JDK已经提供了几种拒绝策略,如下所示:

af18fec07371db8e1f45c6a86582e1d8.png

我们需要自定义决绝策略时,很简单,直接实现RejectedExecutionHandler的rejectedExecution方法即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/442286.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 垃圾回收 null_java方法中把对象置null,到底能不能加速垃圾回收

今天逛脉脉&#xff0c;看见匿名区有人说java中把对做置null&#xff0c;这种做法很菜&#xff0c;不能加速垃圾回收&#xff0c;但是我看到就觉得呵呵了&#xff0c;我是觉得可以加速置null对象回收的。测试的过程中&#xff0c;费劲的是要指定一个合理的测试堆大小&#xff0…

零基础学java web开发pdf_新手学Java Web开发.pdf

作 者 &#xff1a;杨磊等编著出版发行 : 北京&#xff1a;北京希望电子出版社 , 2010.01ISBN号 &#xff1a;978-7-89498-988-8页 数 &#xff1a; 480丛书名 : 新手学编程系列原书定价 : 49.80主题词 : 计算机编程软件&#xff0c;JAVA WEB中图法分类号 : TP3 ( 工业技术->…

java 外卖订餐系统_java外卖订餐系统小项目

本文实例为大家分享了java外卖订餐系统的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下执行结果&#xff1a;通过选择功能序号&#xff0c;执行响应的功能&#xff1a;代码实现&#xff1a;package 外卖订餐系统;/** 代码优点&#xff0c;使用 循环&#xff1a;* 显…

java 字符串包含某个字符_java中判断字符串中是否包含某个特定字符串的方法有哪些...

判断一个字符串是否包含某个子串的n种方法&#xff1a;1、startsWith()方法2、contains()方法3、indexOf方法startsWith()方法这个方法有两个变体&#xff0c;用于检测字符串是否以指定的前缀开始。此方法定义的语法如下:public boolean startsWith(String prefix, int toffset…

java的方法调用中分不清_java中不太清晰的知识点

一、什么包需要导入&#xff0c;什么包不需要导入1.java.lang包的内容是自动导入的&#xff0c;不需要手动导入&#xff0c;其它必须手动导入。2.java.io.OutputStreamWrite已经是完整的类&#xff0c;无需再导入&#xff0c;而printWrite这个类&#xff0c;并不是调用完整的类…

java生命小游戏_Java修炼——飞机生存小游戏

在学习了java入门的课程之后&#xff0c;自己动手跟着老师写的一个小游戏&#xff0c;用的是Frame。总共有七个类。1.飞机游戏的主窗口(MyGameFrame)继承Frame。package com.bjsxt.plane;import java.awt.Color;import java.awt.Font;import java.awt.Frame;import java.awt.Gr…

链队列的基本运算java_链式队列基本操作的实现问题

问题描述&#xff1a;用链式存储方式实现队列的基本操作涉及变量&#xff1a;front&#xff1a;Node型自定义变量&#xff0c;指向队首元素rear&#xff1a;Node型自定义变量&#xff0c;指向队尾元素涉及教材&#xff1a;《数据结构——Java语言描述(第2版)》 清华大学出版社大…

mysql数据库优化看的书_MySQL 数据库优化,看这篇就够了

点击上方"IT牧场"&#xff0c;选择"设为星标"技术干货每日送达&#xff01;来源&#xff1a;segmentfault.com/a/1190000018631870前言数据库优化一方面是找出系统的瓶颈,提高MySQL数据库的整体性能,而另一方面需要合理的结构设计和参数调整,以提高用户的相…

python 升级所有库_自动更新Python所有第三方库

一般python用得比较久以后&#xff0c;就会安装很多第三方的库。比如这是我的pip list情况&#xff1a;pip list而且一屏还显示不完。通过如下命令可以看到需要更新的第三方库&#xff1a;pip list -o需要更新的库而pip提供的更新命令只能一个个的更新...pip install -U 库名 #…

java 反射 类变量_java反射机制取出model类的所有变量,以及value

工作上遇到个问题,顺便解决了,希望对大家有帮助package com.zuidaima.util;public static void main(String[] args) throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException, InstantiationException {Class> obj Class.forName("com.roi…

php 去掉不可见字符串,php去掉指定字符串的办法

php去掉指定字符串的办法&#xff1a;首先创建一个PHP示例文件&#xff1b;然后定义字符串&#xff1b;最后通过“str_replace(array("_","",""),"",$str);”方法去掉指定字符串即可。推荐&#xff1a;《PHP视频教程》用正则可以解决问…

php文件上传并保存路径到数据库,thinkphp表单上传文件并将文件路径保存到数据库中?...

上传单个文件&#xff0c;此文以上传图片为例&#xff0c;上传效果如图所示创建数据库upload_img,用于保存上传路径CREATE TABLE seminar_upload_img ( id int(11) NOT NULL AUTO_INCREMENT, img_name varchar(255) DEFAULT NULL COMMENT 图片名称, img_url varchar(255) DE…

PHP数组的访问方法有几种,数组常用方法有哪些

数组中常用的方法有&#xff1a;1、给数组末尾添加新内容的push方法&#xff1b;2、删除数组最后一项的pop方法&#xff1b;3、删除数组第一项的shift方法&#xff1b;4、向数组首位添加新内容unshift方法等等。数组常用的一些方法&#xff1a;1、push()向数组的末尾添加新内容…

java opcode 反汇编,如何将VM的opcode嵌入汇编源码中

这次来一个关于VM的混淆办法&#xff0c;可能只是个小trick&#xff0c;仅仅来自胡思乱想也许你会觉得很奇怪&#xff0c;一个VM能有啥新鲜的&#xff0c;对&#xff0c;单纯来说VM保护源代码已经非常的成熟了&#xff0c;所以在这里只做最基本的介绍&#xff0c;而且这次的重点…

php ip 合法,什么是合法ip地址

合法的IP地址中&#xff0c;每个三位数都是在0~254之间的&#xff0c;不可能是大于254就连255都不行。这才是合法的IP地址&#xff0c;还有 IP地址有A\B\C类IP。iPv4的ip地址都是(1~255).(0~255).(0~255).(0~255)的格式。A类的IP地址范围为0.0.0.0-127.255.255.255B类的IP地址范…

php session和cookie区别,php中session和cookie的区别是什么?

一、Session(1)Session的由来以及介绍Session:在计算机中&#xff0c;尤其是在网络应用中&#xff0c;称为“会话控制”,生存时间为用户在浏览某个网站时&#xff0c;从进入网站到关闭这个网站所经过的这段时间&#xff0c;也就是用户浏览这个网站所花费的时间。由于Http是一种…

matlab 泡泡图,使用matlab绘制2维、3维气泡图

在学习模糊c均值聚类时&#xff0c;突然想到能否将每个样本对所属簇的奴属度(C)用气泡图的形式表示出来&#xff0c;这样就可以在一张图上同时获得分类与奴属度(C)两类信息。在matlab中没有绘制气泡图的专用函数&#xff0c;不过可以通过手动设置参数&#xff0c;来最终达到气泡…

用vscode可以开发php,【编程开发工具】vscode能够编写php吗

Visual Studio Code一个轻量且壮大的代码编辑器&#xff0c;支撑Windows&#xff0c;OS X和Linux。内置JavaScript、TypeScript和Node.js支撑&#xff0c;而且具有雄厚的插件生态系统&#xff0c;可通过装置插件来支撑C、C#、Python、PHP等其他言语。Visual Studio Code设置php…

ant混淆编译java web,Android中使用ant混淆编译

搞了好几天&#xff0c;查看了上百个网站&#xff0c;最后摸索出一套很简单的ant混淆编译的方法。下面开始&#xff1a;1.拿一个普通项目来说&#xff0c;首先为它加上ant编译功能。android update project --name project_name -t 3 -p D:/temp/project_name此时会在项目根目录…

matlab漂亮图表,漂亮,美观的图表之Matlab强势回归~~~~走你8

今天来画3D plot% Load the dataload latticeExamplexx x(:);yy y(:);zz z(:);% locate the non-zero pointsa find(T~0);% plot the non-zero points using a scatter plot% use the values of T to represent both color and size of symbolsscatter3(xx(a),yy(a),zz(a),…