Java线程池ThreadPoolExecutor的实例

Java.util中的线程池和Spring框架对这个类的扩展
1.单独通过java里的ThreadPoolExecutor这个类,可以创建线程池,如果系统采用Spring框架设计,可以采用ThreadPoolTaskExecutor这个类来扩展控制,这个对维护线程池
最大值和最小值易扩展(这个可以在配置文件里修改)。其他Spring框架里ThreadPoolTaskExecutor是对ThreadPoolExecutor这个类进行了一层包装。
在多线程大师Doug Lea的贡献下,在JDK1.5中加入了许多对并发特性的支持,例如:线程池。

一、简介
线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)corePoolSize:线程池维护线程的最少数量
maximumPoolSize:线程池维护线程的最大数量
keepAliveTime: 线程池维护线程所允许的空闲时间
unit: 线程池维护线程所允许的空闲时间的单位
workQueue: 线程池所使用的缓冲队列
handler: 线程池对拒绝任务的处理策略
一个任务通过 execute(Runnable)方法被添加到线程池,任务就是一个 Runnable类型的对象,任务的执行方法就是 Runnable类型对象的run()方法。
当一个任务通过execute(Runnable)方法欲添加到线程池时:
如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。
也就是:处理任务的优先级为:
核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
unit可选的参数为java.util.concurrent.TimeUnit中的几个静态属性:
NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS。
workQueue我常用的是:java.util.concurrent.ArrayBlockingQueue
handler有四个选择:
    1.ThreadPoolExecutor.AbortPolicy()
    抛出java.util.concurrent.RejectedExecutionException异常
    2.ThreadPoolExecutor.CallerRunsPolicy()
    重试添加当前的任务,他会自动重复调用execute()方法
    3.ThreadPoolExecutor.DiscardOldestPolicy()
    抛弃旧的任务
    4.ThreadPoolExecutor.DiscardPolicy()
    抛弃当前的任务

二、一般用法举例

import java.io.Serializable;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class TestThreadPool {private static int produceTaskSleepTime = 2;private static int consumeTaskSleepTime = 2000;private static int produceTaskMaxNumber = 10;public static void main(String[] args) {//构造一个线程池ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3,TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3),new ThreadPoolExecutor.DiscardOldestPolicy());for(int i=1;i<=produceTaskMaxNumber;i++){try {//产生一个任务,并将其加入到线程池String task = "task@ " + i;System.out.println("put " + task);threadPool.execute(new ThreadPoolTask(task));//便于观察,等待一段时间Thread.sleep(produceTaskSleepTime);} catch (Exception e) {e.printStackTrace();}}}/*** 线程池执行的任务* @author hdpan*/public static class ThreadPoolTask implements Runnable,Serializable{private static final long serialVersionUID = 0;//保存任务所需要的数据private Object threadPoolTaskData;ThreadPoolTask(Object tasks){this.threadPoolTaskData = tasks;}public void run(){//处理一个任务,这里的处理方式太简单了,仅仅是一个打印语句System.out.println("start .."+threadPoolTaskData);try {便于观察,等待一段时间Thread.sleep(consumeTaskSleepTime);} catch (Exception e) {e.printStackTrace();}threadPoolTaskData = null;}public Object getTask(){return this.threadPoolTaskData;}}
}

说明:
1、在这段程序中,一个任务就是一个Runnable类型的对象,也就是一个ThreadPoolTask类型的对象。
2、一般来说任务除了处理方式外,还需要处理的数据,处理的数据通过构造方法传给任务。
3、在这段程序中,main()方法相当于一个残忍的领导,他派发出许多任务,丢给一个叫 threadPool的任劳任怨的小组来做。
这个小组里面队员至少有两个,如果他们两个忙不过来,任务就被放到任务列表里面。
如果积压的任务过多,多到任务列表都装不下(超过3个)的时候,就雇佣新的队员来帮忙。但是基于成本的考虑,不能雇佣太多的队员,至多只能雇佣 4个。
如果四个队员都在忙时,再有新的任务,这个小组就处理不了了,任务就会被通过一种策略来处理,我们的处理方式是不停的派发,直到接受这个任务为止(更残忍!呵呵)。
因为队员工作是需要成本的,如果工作很闲,闲到 3SECONDS都没有新的任务了,那么有的队员就会被解雇了,但是,为了小组的正常运转,即使工作再闲,小组的队员也不能少于两个。
4、通过调整 produceTaskSleepTime和 consumeTaskSleepTime的大小来实现对派发任务和处理任务的速度的控制,改变这两个值就可以观察不同速率下程序的工作情况。
5、通过调整4中所指的数据,再加上调整任务丢弃策略,换上其他三种策略,就可以看出不同策略下的不同处理方式。

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

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

相关文章

win7系统电脑语言栏怎么更换输入法

我们在使用win7操作系统电脑的时候&#xff0c;有些情况下我们可能会想要更换自己的输入法&#xff0c;但是还是有很多小伙伴不知道应该怎么操作。那么对于这个问题小编觉得我们可以通过电脑键盘上面的快捷键来进行操作&#xff0c;也可以使用鼠标在任务栏唤出相关的设置选项即…

记一次生成唯一ID的问题

之前一直用new Date().getTime()作为ID一直没出现啥问题&#xff0c;但是在测试环境被测试人员发现问题了&#xff0c;最终定位到是一个循环体中多次循环所取到的ID竟然是一样的&#xff01;也就是说系统在1ms之内做了好几次sql操作&#xff01;好吧&#xff0c;万万没想到。。…

2345浏览器如何启用过滤弹窗广告

2345浏览器是一款非常便捷的浏览服务软件&#xff0c;有很多用户都会使用手机浏览更多的信息&#xff0c;随时都可以享受便捷的服务&#xff0c;使用过的用户都会知道&#xff0c;浏览器的资讯会有广告&#xff0c;其实在看视频的时候也会有广告&#xff0c;那么要怎么过滤弹窗…

Jersey中ContainerRequestFilter的使用

手头上有对所有请求做权限认证的需求&#xff0c;必须要在执行rest方法之前判断用户是否是登录状态&#xff0c;也就是要判断session存不存在&#xff0c;这里使用ContainerRequestFilter&#xff0c;从名字上也能看出来它是一个过滤器&#xff0c;会将所有请求拦截下来&#x…

手机腾讯视频软件如何开启护眼功能

今天给大家简单介绍一下&#xff0c;在手机腾讯视频中&#xff0c;如何开启护眼功能&#xff0c;具体步骤如下&#xff1a; 1、首先&#xff0c;打开手机苏宁易购app; 手机腾讯视频软件如何开启护眼功能 2、进入软件时先点击【跳过】广告页面&#xff0c;如图 手机腾讯视频…

XML解析-Dom4j的DOM解析方式更新XML

Dom4j工具,是非官方的&#xff0c;不在jdk中。 使用步骤&#xff1a; 1&#xff09;导入dom4j的核心包。 dom4j-1.6.1.jar 2&#xff09;编写Dom4j读取xml文件的代码 1、更新XML 1.1、写出内容到xml文档 package com.rk.xml.g_dom4j_write;import java.io.File; import java.io…

爱奇艺如何设置最小化显示在托盘

相信很多朋友都有在使用爱奇艺&#xff0c;那么大家对食物爱奇艺的过程当中如何设置最小化显示在托盘呢?关于这个问题小编就和大家分享一下我的经验&#xff0c;希望能够帮助到大家。 爱奇艺会员活动2020_爱奇艺如何设置最小化显示在托盘 1、首先点击电脑桌面中的爱奇艺&…

傲游浏览器怎么看网页源代码 网页源代码查看方法简述

网页源代码&#xff0c;顾名思义就是指在网页制作过程中需要用到的一些特殊的“语言”&#xff0c;设计人员向通过对这些“语言”进行组织编排制作出网页&#xff0c;再由浏览器进行“翻译”后才会出现用户最终看到的效果。那么&#xff0c;在傲游浏览器中该怎么看网页源代码呢…

Qt前端技术:5.QSS

这个是表示QFrame中的pushButton中的子类和它子类的子类都将背景变为red 写成大于的时候表示只有直接的子类对象才会变 这个图中的QGroupBox和QPushButton都是QFrame的直接的子类 这个中的QGroupBox是QFrame的直接的子类但是QPushButton 是QGroupBox的子类&#xff0c;QPushB…

Spring定时任务的几种实现

近日项目开发中需要执行一些定时任务&#xff0c;比如需要在每天凌晨时候&#xff0c;分析一次前一天的日志信息&#xff0c;借此机会整理了一下定时任务的几种实现方式&#xff0c;由于项目采用spring框架&#xff0c;所以我都将结合 spring框架来介绍。 一&#xff0e;分类 从…

搜狗高速浏览器主页被篡改怎么办 搜狗浏览器中恢复被篡改主页的方法

搜狗浏览器是一款还不错的浏览器&#xff0c;我们在使用搜狗浏览器的过程中发现主页被篡改怎么办呢?接下来我们一起往下看看搜狗浏览器中恢复被篡改主页的方法吧。 方法步骤 1、首先打开我的搜狗浏览器发现我的主页已经被篡改成hao123的主页了; 搜狗高速浏览器主页被篡改怎…

解决quartz的job无法注入spring对象

一般情况下&#xff0c;quartz的job中使用autowired注解注入的对象为空&#xff0c;这时候我们就要使用spring-quartz提供的AdaptableJobFactory类。 自定义一个类: [java] view plaincopy public class JobFactory extends AdaptableJobFactory { Autowired …

谷歌Chrome浏览器如何开启无痕模式 Chrome浏览器无痕模式开启方法

在访问一些特殊网站时&#xff0c;许多人都会开启浏览器自带的无痕模式&#xff0c;以免除一些不必要的麻烦。那么&#xff0c;谷歌Chrome浏览器要如何开启无痕模式呢?不清楚操作方法的朋友&#xff0c;不妨参考一下小编分享的Chrome浏览器无痕模式开启方法。 方法步骤 点击…

搜狗浏览器怎么实现图标旋转 搜狗浏览器实现图标旋转的方法

搜狗浏览器是一款大家经常使用的浏览器&#xff0c;你到知道搜狗浏览器中有一个非常有趣的功能就是图标旋转&#xff0c;那你知道在搜狗浏览器是怎么实现图标旋转的吗?接下来我们呢一起往下看看搜狗浏览器实现图标旋转的方法吧。 方法步骤 1、打开搜狗浏览器动态图标插件的下…

AngularJS+Jersey下载excel

AngularJS代码&#xff1a; $scope.testDownload function () { $http.post("rest/excel/down", $scope.req, {responseType:arraybuffer}).success(function (data) { varblob new Blob([data], {type:"application/vnd.ms-excel"}); varfileName "…

火狐浏览器摄像头权限怎么开启 火狐浏览器摄像头权限开启的方法

火狐浏览器是我们大家经常使用的浏览器之一&#xff0c;在使用这款浏览器的过程有时候需要使用到摄像头&#xff0c;那你知道火狐浏览器摄像头权限怎么开启的吗?接下来我们一起往下看看火狐浏览器摄像头权限开启的方法吧。 方法步骤 1、打开火狐浏览器&#xff0c;点击右上角…

Activiti 基础概念

1、ProcessInstance 与ProcessDefinition 流程实例&#xff08;ProcessInstance&#xff09;和流程定义&#xff08;ProcessDefinition&#xff09;的关系&#xff0c;与类和实例对象的关系有点像&#xff0c;ProcessDefinition是整个流程步骤的说明而ProcessInstance就是指流程…

优酷视频如何修改账号密码?

一.pc端&#xff1a;您能够立即登陆【点一下这儿】密码重置哦~或是能够按下列方式实际操作哦。 1.登陆本站&#xff0c;网页页面最上边【登陆】功能键&#xff0c;登陆界面右下角点一下【密码忘了】。 优酷视频如何修改账号密码&#xff1f; 2.请输入的手机上/电子邮箱&…

MD5加密工具类

这是一个个人认为非常好用的使用MD5salt加密的工具类&#xff0c;一部分代码由网上搜索而得&#xff0c;一部分自己修改添加之后而得。使用这个工具类&#xff0c;非常简单&#xff0c;从前台拿到密码passwd&#xff0c;直接HexUtil.getEncryptedPwd(passwd)就可以返回一个长度…

win7系统笔记本电脑开机蓝屏怎么办

我们在使用电脑的时候难免不了会y遇到一些问题&#xff0c;比如电脑蓝屏或者黑屏的情况出现&#xff0c;就有一位win7系统用户遇到了笔记本电脑开机蓝屏的情况&#xff0c;win7系统笔记本电脑开机蓝屏怎么办?就此问题&#xff0c;让我们一起来聊聊windows7笔记本电脑开机蓝屏解…