`

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
分享到:
评论

相关推荐

    Java8并行流中自定义线程池操作示例

    主要介绍了Java8并行流中自定义线程池操作,结合实例形式分析了并行流的相关概念、定义及自定义线程池的相关操作技巧,需要的朋友可以参考下

    基于Java开发的智能电表采集系统源码+项目说明书.zip

    【项目介绍】 基于Java开发的智能电表采集系统源码+项目说明书.zip 该资源内项目代码都是经过测试运行成功,功能ok...使用java编写的智能电表采集系统,使用线程池进行采集,采集频率为5S,实现电表协议解析存入数据库

    Java 7并发编程实战手册

    《Java 7并发编程实战手册》适合具有一定Java编程基础的读者阅读和学习。如果你是一名Java开发人员,并且想进一步掌握并发编程和多线程技术,并挖掘Java 7并发的新特性,那么本书是你的合适之选。 《Java 7并发编程...

    java编写的智能电表采集系统,使用线程池进行采集,采集频率为5S,实现电表协议解析存入数据库.zip

    各领域数据集,工具源码,...云计算与大数据:数据集、包括云计算平台、大数据分析、人工智能、机器学习等,云计算是一种基于互联网的计算方式,通过这种方式,共享的软硬件资源和信息可以按需提供给计算机和其他设备。

    基于短信应用的SP服务平台java源码

    通讯接口均参照标准协议实现未使用任何第三方的API,我们可以通过灵活的配置以支持不同的运营商(经实际测试和不同的网关厂商兼容性均良好)。 *关键技术:系统使用了线程池、消息队列、数据库连接池、socket连接池等...

    Java并发编程(学习笔记).xmind

    活跃度(Liveness)、性能、测试 避免活跃性危险 死锁 锁顺序死锁 资源死锁 动态的锁顺序死锁 开放调用 在协作对象之间发生的死锁 死锁的避免与诊断 支持定时的显示锁 通过...

    Java并发编程实战

    本书深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则...

    java范例开发大全源代码

     1.2.4 测试JDK配置是否成功 7  实例1 开发第一个Java程序 7  第2章 Java基础类型与运算符(教学视频:39分钟) 9  2.1 基础类型 9  实例2 自动提升 9  实例3 自动转换 10  实例4 常用基础类型之...

    java范例开发大全

    实例242 手术任务(线程池) 462 实例243 模拟人工服务台(线程连接池) 466 13.6 线程应用实例 471 实例244 下雪的村庄 472 实例245 小飞侠 474 实例246 飞流直下 477 实例247 多线程断点续传 479 实例248 滚动的...

    Java范例开发大全 (源程序)

     1.2.4 测试JDK配置是否成功 7  实例1 开发第一个Java程序 7  第2章 Java基础类型与运算符(教学视频:39分钟) 9  2.1 基础类型 9  实例2 自动提升 9  实例3 自动转换 10  实例4 常用基础类型之强制...

    阿里巴巴编码规范 基础技能认证 考题分析(考题+答案).docx

    测试数据使用独立的测试库。 C .自动回滚单元测试产生的脏数据。 D .无须区别,统一在业务代码中进行判断和识别。 多选 2.关于并发处理,下列哪些说法符合《阿里巴巴Java开发手册》:ABC A .线程资源必须通过...

    基于JavaWeb数据分析的关键词分析系统源码+项目使用说明.zip

    1、该资源内项目代码都是经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也...

    Java范例开发大全(全书源程序)

    1.2.4 测试JDK配置是否成功 7 实例1 开发第一个Java程序 7 第2章 Java基础类型与运算符 实例2 自动提升 9 实例3 自动转换 10 实例4 常用基础类型之强制转换 11 2.2 运算符 12 实例5 算术运算符 12 实例6 ...

    javaconcurrent源码-java7-source-code:Java7源码/Concurrency同步

    线程基础/同步sync/并发concurrent/容器/线程池 示例代码 JUC容器的源码解析 Synchronized 同步容器 Concurrent 并发容器: Map/List/Queue 阻塞队列 JUC锁: CountDownLatch 闭锁 AQS 锁的公共类 20180514 String, ...

    java范例开发大全(pdf&源码)

    1.2.4 测试JDK配置是否成功 7 实例1 开发第一个Java程序 7 第2章 Java基础类型与运算符(教学视频:39分钟) 9 2.1 基础类型 9 实例2 自动提升 9 实例3 自动转换 10 实例4 常用基础类型之强制转换 11 2.2 运算符 12 ...

    王者荣耀java源码-TechnicalArticles:技术文章

    王者荣耀java源码 标题 分类 内容 备注 架构 MySQL MQ 服务器 算法 JVM CODE JVM 缓存 使用redis改善数据库压力并更加实际情况定制 MQ 算法 缓存 缓存 解决缓存一致性3种方案 缓存 饿了么hotkey解决方案 IO 流程图及...

    开涛高可用高并发-亿级流量核心技术

    12.3.1 Java线程池 245 12.3.2 Tomcat线程池配置 248 13 异步并发实战 250 13.1 同步阻塞调用 251 13.2 异步Future 252 13.3 异步Callback 253 13.4 异步编排CompletableFuture 254 13.5 异步Web服务实现 257 13.6 ...

    异步并行加载工具Asyncload.zip

    针对方法调用,基于字节码增强技术,运行时生成代理类,快速返回mock对象,后台异步进行调用通过管理和调度线程池,将后台异步调用进行加速处理,达到一个平衡点业务执行过程需要获取mock对象的真实数据时,阻塞等待...

Global site tag (gtag.js) - Google Analytics