`

Java线程池的测试和分析

阅读更多

 

package cn.smallbug.jdk.concurrent.exe;

import java.io.Serializable;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.DiscardPolicy;
import java.util.concurrent.TimeUnit;

import org.junit.Before;
import org.junit.Test;

public class TestThreadPoolExecutor {

	private ThreadPoolExecutor pool = null;

	@Before
	public void before() {
		this.pool = new ThreadPoolExecutor(//
				/**
				 * corePoolSize(线程池的基本大小):<br />
				 * 当提交一个任务到线程池时,线程池会创建一个线程来执行任务,
				 * 即使其他空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任务数大于线程池基本大小时就不再创建。
				 * 如果调用了线程池的prestartAllCoreThreads方法,线程池会提前创建并启动所有基本线程。
				 */
				10,
				/**
				 * maximumPoolSize(线程池最大大小):<br />
				 * 线程池允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。
				 * 值得注意的是如果使用了无界的任务队列这个参数就没什么效果。
				 */
				20,
				/**
				 * keepAliveTime(线程活动保持时间):<br />
				 * 线程池的工作线程空闲后,保持存活的时间。
				 */
				1000,
				/**
				 * TimeUnit(线程活动保持时间的单位):<br />
				 * 可选:<br />
				 * <ul>
				 * <li>单位有天(DAYS)</li>
				 * <li>小时(HOURS)</li>
				 * <li>分钟(MINUTES)</li>
				 * <li>毫秒(MILLISECONDS)</li>
				 * <li>微秒(MICROSECONDS, 千分之一毫秒)</li>
				 * <li>毫微秒(NANOSECONDS, 千分之一微秒)</li>
				 * </ul>
				 */
				TimeUnit.MILLISECONDS, // 表示线程活动保持时间为1000ms,
				/**
				 * runnableTaskQueue(任务队列):<br />
				 * 用于保存等待执行的任务的阻塞队列。可以选择以下几个阻塞队列:
				 * <ul>
				 * <li><b>ArrayBlockingQueue:</b>是一个基于数组结构的有界阻塞队列,此队列按
				 * FIFO(先进先出)原则对元素进行排序。</li>
				 * <li><b>LinkedBlockingQueue:</b>一个基于链表结构的阻塞队列,此队列按FIFO (先进先出)
				 * 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.
				 * newFixedThreadPool()使用了这个队列。</li>
				 * <li><b>SynchronousQueue:</b>
				 * 一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,
				 * 否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.
				 * newCachedThreadPool使用了这个队列。</li>
				 * <li><b>PriorityBlockingQueue:</b>一个具有优先级的无限阻塞队列。</li>
				 * </ul>
				 */
				new ArrayBlockingQueue<Runnable>(100),
				/**
				 * ThreadFactory:<br />
				 * 用于设置创建线程的工厂,可以通过线程工厂给每个创建出来的线程设置更有意义的名字,Debug和定位问题时非常又帮助。
				 */
				// new CreateThread(),
				/**
				 * RejectedExecutionHandler(饱和策略):<br />
				 * 当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。
				 * 这个策略默认情况下是AbortPolicy,表示无法处理新任务时抛出异常。以下是JDK1.5提供的四种策略
				 * <ul>
				 * <li>CallerRunsPolicy:只用调用者所在线程来运行任务。</li>
				 * <li>DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。</li>
				 * <li>DiscardPolicy:不处理,丢弃掉。</li>
				 * <li>当然也可以根据应用场景需要来实现RejectedExecutionHandler接口自定义策略。
				 * 如记录日志或持久化不能处理的任务。</li>
				 * </ul>
				 */
				new DiscardPolicy()//
		);
	}

	/**
	 * 线程池在创建时如果指定任务工厂execute的任务将无效
	 * 
	 * @timestamp Mar 19, 2016 3:08:56 PM
	 */
	@Test
	public void testExecute() {
		pool.execute(new Runnable() {

			@Override
			public void run() {
				System.out.println(2 + 2);
			}

		});
	}

	/**
	 * 线程池在创建时如果指定任务工厂execute的任务将无效
	 * 
	 * @timestamp Mar 19, 2016 3:11:21 PM
	 */
	@Test
	public void testSubmit() {
		int i = 100;
		while (i-- > 0) {
			pool.submit(//
					new Callable<Serializable>() {

						@Override
						public Serializable call() throws Exception {
							return 2 + 2;
						}
					}//
			);
		}
		Future<Serializable> result = pool.submit(//
				new Callable<Serializable>() {

					@Override
					public Serializable call() throws Exception {
						return 2 + 2;
					}
				}//
		);
		Serializable s = null;
		try {
			s = (int) result.get();
		} catch (InterruptedException e) {
			// 处理中断异常
			e.printStackTrace();
		} catch (ExecutionException e) {
			// 处理无法执行任务异常
			e.printStackTrace();
		} finally {
			stastic(pool);
			/**
			 * 1、将线程池的状态设置成SHUTDOWN状态<br />
			 * 2、然后中断所有没有正在执行任务的线程
			 */
			pool.shutdown();
			/**
			 * 1、将线程池的状态设置成STOP<br />
			 * 2、遍历线程池中的工作线程<br />
			 * 3、逐个调用线程的interrupt方法来中断线程(无法响应中断的任务可能永远无法终止)<br />
			 * 4、返回等待执行任务的列表
			 */
			// pool.shutdownNow();
			/**
			 * 只要调用了这两个关闭方法的其中一个,isShutdown方法就会返回true<br />
			 * 当所有的任务都已关闭后,才表示线程池关闭成功,这时调用isTerminaed方法会返回true<br />
			 * 通常调用shutdown来关闭线程池,如果任务不一定要执行完,则可以调用shutdownNow
			 */
		}
		System.out.println(s);

	}

	/**
	 * 通过继承线程池并重写线程池的 <br />
	 * beforeExecute <br />
	 * afterExecute <br />
	 * terminated <br />
	 * 方法,可以在任务执行前, 执行后和线程池关闭前干一些事情。如监控任务的平均执行时间,最大执行时间和最小执行时间等。
	 * 
	 * @timestamp Mar 19, 2016 3:37:29 PM
	 * @param pool2
	 */
	private void stastic(ThreadPoolExecutor pool) {
		System.out.println("current cpu num -> " + Runtime.getRuntime().availableProcessors());
		System.out.println("线程池需要执行的任务数量 -> " + pool.getTaskCount());
		System.out.println("线程池在运行过程中已完成的任务数量。小于或等于taskCount -> " + pool.getCompletedTaskCount());
		System.out.println("线程池曾经创建过的最大线程数量 -> " + pool.getLargestPoolSize());
		System.out.println("线程池的线程数量。如果线程池不销毁的话,池里的线程不会自动销毁,所以这个大小只增不减 -> " + pool.getPoolSize());
		System.out.println("获取活动的线程数 -> " + pool.getActiveCount());
	}

	/**
	 * 工作任务创建工厂
	 * 
	 * @timestamp Mar 19, 2016 3:01:24 PM
	 * @author smallbug
	 */
	class CreateThread implements ThreadFactory {
		@Override
		public Thread newThread(Runnable r) {
			return new Thread() {
				@Override
				public void run() {
					System.out.println(1 + 1);
				}
			};
		}

	}
}

 
          

 

 

  1. 首先线程池判断基本线程池是否已满?没满,创建一个工作线程来执行任务。满了,则进入下个流程。
  2. 其次线程池判断工作队列是否已满?没满,则将新提交的任务存储在工作队列里。满了,则进入下个流程。
  3. 最后线程池判断整个线程池是否已满?没满,则创建一个新的工作线程来执行任务,满了,则交给饱和策略来处理这个任务。

参考博客:聊聊并发(三)Java线程池的分析和使用

  • 大小: 64.4 KB
1
3
分享到:
评论

相关推荐

    20220607R4s9F6ZH.zip

    20220607R4s9F6ZH.zip

    【计算机求职笔试】资源

    【计算机求职笔试】资源

    基于S7-200 PLC与组态王的智能楼宇消防系统设计与实现

    内容概要:本文详细介绍了基于西门子S7-200 PLC和组态王软件构建的智能楼宇消防系统的设计与实现。首先阐述了硬件配置,包括烟雾传感器、手动报警按钮、排烟风机和声光报警器等设备的连接方式及其IO分配。接着深入解析了梯形图编程的关键逻辑,如输入滤波设置、分层报警策略以及带时间锁的控制流程。同时探讨了组态王监控画面的设计要点,特别是权限管理和报警弹窗的脚本实现。此外,还分享了一些常见的调试问题及解决方案,如电磁阀误动作、信号干扰等问题的处理方法。最终展示了系统的性能优势,强调了实时监测与快速响应的重要性。 适合人群:从事楼宇自动化、工业控制系统设计的技术人员,尤其是对PLC编程和SCADA系统有一定了解的工程师。 使用场景及目标:适用于新建或改造智能楼宇消防系统的项目规划与实施。目标是提高消防系统的响应速度和可靠性,确保在火灾发生时能够迅速采取措施,保障人员生命财产安全。 其他说明:文中提供了大量实际案例和经验教训,有助于读者更好地理解和应用相关技术和方法。

    2025姓名配对测算系统最新源码 带后台

    2025姓名配对测算系统最新源码 带后台 一套网上全新的UI,用于姓名配对,支持投流各大平台,全开源可进行二开! 投流的老板可以放心使用这套 后台登录地址:/admin    账号admin    密码admin123

    基于LabVIEW的多路压力数据采集系统设计与实现

    内容概要:本文详细介绍了基于LabVIEW构建的多路压力数据采集系统的硬件配置和软件架构。硬件方面,选择了合适的传感器(如STC的CYZ-102)和信号调理模块(如NI的SCXI-1520),确保系统的精度和稳定性。软件部分强调了DAQ助手的使用、生产者-消费者模式的应用以及TDMS格式的数据存储方法。此外,还分享了许多实用技巧,如差分输入应对电磁干扰、波形图控件优化、数据存储的块大小设置等。通过这些措施,系统实现了高效稳定的多通道压力数据采集,显著缩短了设备故障排查时间。 适合人群:从事工业自动化、数据采集系统设计的技术人员,尤其是有一定LabVIEW基础的研发人员。 使用场景及目标:适用于需要进行多通道压力监测的工业环境,如化工厂、液压测试台等。主要目标是提高数据采集的效率和准确性,减少设备故障排查时间,提升生产效率。 其他说明:文中提供了大量具体的配置代码和实践经验,帮助读者更好地理解和应用相关技术。同时,作者还分享了一些调试过程中遇到的问题及其解决方案,为后续开发提供宝贵的经验参考。

    S0073基于JavaSSM框架民宿管理系统1725784419.rar

    本资源为基于Java的SSM框架民宿管理系统的完整代码,适用于【计算机专业毕设/课设】。通过该项目,您可以快速实现民宿管理相关功能,并且该代码已进行了充分的注释和优化,便于开发者快速理解和二次开发。 资源特色: 功能齐全: 高效实现:代码经过优化,性能稳定, 详细注释:每个模块和函数均附带详细注释,便于理解和学习。帮助您快速上手和部署。 易于扩展:代码结构清晰,方便进行二次开发和功能拓展。 适用人群: 初学者:帮助您快速了解并实现[技术/功能]。 开发者:提供高效的代码实现,助力项目开发。 学术研究:为相关领域的研究人员提供有价值的代码资源。 下载说明: 本资源为付费资源,购买后可获得完整代码 支持提供技术支持,若有问题请及时联系我们。

    tbb-devel-2018.2-9.el8.x64-86.rpm.tar.gz

    1、文件说明: Centos8操作系统tbb-devel-2018.2-9.el8.rpm以及相关依赖,全打包为一个tar.gz压缩包 2、安装指令: #Step1、解压 tar -zxvf tbb-devel-2018.2-9.el8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm

    大学生智能消费记账系统的设计与实现.zip

    Java项目基于Springboot框架的课程设计,包含LW+ppt

    软考初级信息处理技术员上午试题模拟20及答案

    软考

    使用Matlab辅助设计开关电源.zip

    matlab

    西门子S7-200 SMART与施耐德ATV71变频器自动握手通讯方案及应用

    内容概要:本文详细介绍了如何通过西门子S7-200 SMART PLC与施耐德ATV71变频器建立稳定的自动握手通讯方案。主要内容涵盖硬件连接、参数设置、PLC编程实现DriveCom协议状态机、数据校验方法以及触摸屏配置等方面。文中特别强调了断电重启后的自动恢复机制,确保设备能够快速恢复正常运行,避免人工干预。同时,提供了具体的代码片段和注意事项,帮助读者理解和实施这一解决方案。 适合人群:从事工业自动化领域的工程师和技术人员,特别是那些负责变频器通讯和控制系统集成的专业人士。 使用场景及目标:适用于需要提高工业现场设备自动化水平的企业,旨在解决变频器断电重启后需要人工重新准备的问题,提升系统的稳定性和可靠性。 其他说明:本文不仅提供理论指导,还包括大量实战经验和具体案例分享,有助于读者更好地掌握相关技术和应对实际问题。

    在线考试系统.zip

    Java项目基于Springboot框架的课程设计,包含LW+ppt

    基于SUMO的交通仿真模型研究:信号控制、边界管理与车辆编队技术的应用

    内容概要:本文详细探讨了利用SUMO进行交通仿真的多个关键方面,包括但不限于信号控制、边界管理和车辆编队。首先介绍了通过TraCI接口实现的动态信号灯控制方法,能够根据实时交通状况调整绿灯时长,从而有效降低车辆延误率。其次讨论了高速公路的流量控制策略,如采用渐进式的流速控制和可变限速区来避免因事故造成的严重拥堵。此外,还展示了如何通过协同式自适应巡航控制系统(CACC)实现高效的车辆编队运行,确保车队内部的安全性和稳定性。文中提供了具体的Python代码示例以及XML配置片段,帮助读者更好地理解和实施相关技术。 适合人群:交通工程专业学生、研究人员和技术开发者,特别是对智能交通系统感兴趣的从业者。 使用场景及目标:适用于需要评估不同交通管理策略效果的研究机构或企业;旨在提高城市道路交通效率、减少交通事故发生频率并改善驾驶体验的技术创新项目。 其他说明:作者强调了交通控制参数非线性的特点,并指出在实践中应当灵活运用各种工具和技术手段不断优化仿真模型。同时提醒使用者注意细节之处(如相位编号从零开始),并且鼓励大家充分利用SUMO提供的可视化功能辅助调参工作。

    matlab实现全球定位系统GPS信号产生、捕获与追踪的深度研究-GPS-信号处理-伪随机码-三边测量-多路径效应修正-matlab

    内容概要:本文详细探讨了全球定位系统(GPS)的信号产生、捕获和追踪三个核心步骤,并通过Matlab源码实现相关算法。首先介绍了GPS信号产生的关键要素,包括伪随机码生成、数据编码和信号发射。接着讨论了信号捕获过程,涉及天线接收、码相位测量及其常用方法如滑动相关法。最后阐述了信号追踪的三边测量原理及误差修正措施,如电离层延迟补偿、地形效应补偿和多路径效应修正。通过具体Matlab代码示例展示了整个流程的实现,并附带了详细的运行步骤和结果分析。 适合人群:对GPS系统有兴趣的研究人员和技术爱好者,尤其是有一定编程基础并希望深入了解GPS内部机制的人群。 使用场景及目标:适用于学术研究、工程开发等领域,旨在帮助读者掌握GPS信号处理的基本理论和实践技能,提升定位精度和可靠性。 其他说明:文中提供的Matlab代码已在特定版本下测试通过,但不同版本可能存在差异。此外,还列举了一些参考文献供进一步学习。

    IT技术交流和分享平台的设计与实现.zip

    Java项目基于Springboot框架的课程设计,包含LW+ppt

    P2并联架构Cruise仿真模型与Simulink控制策略解析及应用

    内容概要:本文详细介绍了基于P2并联架构的Cruise仿真模型及其Simulink控制策略。首先,文章阐述了模型架构,特别是P2电机的位置选择以及行星齿轮组的参数配置,强调了扭矩耦合的优势。接着,深入探讨了控制策略,包括三层状态机嵌套的工况识别模块、滑动窗口方差计算用于预判驾驶意图、带遗忘因子的递推最小二乘法进行动态扭矩分配等关键技术。此外,文章还展示了速度跟随模块采用的带前馈的PID控制算法,并讨论了模型验证过程中遇到的问题及解决方案。最后,作者分享了一些有趣的彩蛋和隐藏功能,如秋名山模式和实时参数调整模块,以及模型的实际性能提升情况。 适合人群:从事汽车控制系统研究、混合动力汽车开发的技术人员,尤其是熟悉Matlab/Simulink平台的研发人员。 使用场景及目标:适用于希望深入了解P2并联架构Cruise仿真模型的设计原理和技术细节的研究者;旨在帮助开发者掌握先进的控制策略实现方法,提高仿真模型的精度和效率。 其他说明:文中提供了详细的代码片段和参数设置指南,便于读者理解和复现实验结果。同时,作者提醒读者注意一些潜在的技术陷阱,并给出了相应的解决建议。

    在线互动学习网站设计.zip

    Java项目基于Springboot框架的课程设计,包含LW+ppt

    MATLAB概率风电功率预测.zip

    matlab

    STM32三轴运动控制:基于F1/F4的直线与圆弧插补及加减速算法实现

    内容概要:本文详细介绍了基于STM32F1和STM32F4的三轴运动控制系统源代码及其核心算法。系统实现了直线插补、圆弧插补以及梯形加减速控制,适用于雕刻机和CNC设备。文中提供了详细的中文注释,帮助初学者理解和修改代码。主要特点包括:使用定点数运算提高效率、F4版本利用DSP库进行加速、硬件驱动层针对不同芯片进行了优化配置。 适合人群:具备嵌入式开发基础,尤其是对STM32系列MCU有一定了解的研发人员和技术爱好者。 使用场景及目标:①学习并掌握三轴运动控制的基本原理和实现方法;②应用于雕刻机、CNC机床等需要精确运动控制的场合;③通过修改和扩展现有代码,满足特定应用场景的需求。 其他说明:代码中包含了丰富的调试提示和错误处理机制,有助于快速定位和解决问题。此外,项目结构清晰,便于进一步的功能扩展和技术研究。

Global site tag (gtag.js) - Google Analytics