线程相关 之 ThreadPoolExecutor简单用法【3】

本文详细介绍了如何使用ThreadPoolExecutor创建自定义线程池,包括如何添加前置、后置以及线程结束后的处理逻辑。同时,文章讨论了线程池参数的含义和拒绝策略的触发条件,确保在触发拒绝策略时,已提交任务的处理不受影响。

1、介绍了基于ThreadPoolExecutor,增加前置,后置以及线程结束后处理的接口扩展。

2、参数的用法,含义,以及触发拒绝策略的机制和条件。

package demo.collection;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolExecutorTest extends ThreadPoolExecutor{
	
	public static void main(String[] args) {
		ThreadPoolExecutorTest executorTest = new ThreadPoolExecutorTest(3, 5, 2, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3));
		// 首先创建3个核心线程,后边继续提交4/5/6任务时,核心线程都在处理任务,所以后续提交的3个任务都放在队列中
		// 继续提交7/8两个任务,因为队列已满,但此时线程数未达到最大线程数,所以继续创建线程,达到最大线程数
		// 继续创建9个线程,此时触发拒绝策略,进入拒绝策略制定的逻辑进行处理。
		//
		// tips:上边的分析过程,有一个前提:这个前提就是:任务提交的速度>任务处理的速度。
		// 如果:在提交任务时,加上适当的延迟,那么即使其他条件完全保持不变,也可以正常处理完所有的任务,而不会进入拒绝逻辑中。
		for (int index = 0 ;index <15;index ++){
			System.out.println("ThreadPoolExecutorTest.main() create thread index :"+(index+1));
			try {
				Thread.sleep(4); // 提交任务加上适当的延迟,如果想要看到进入拒绝策略的效果,注释这样代码
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			executorTest.execute(new MyThread()) ; // 创建任务并提交
		}
		boolean flag = true;
		while(flag){
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			if (executorTest.getActiveCount()<=0){ // 当没有活动线程时,可以关闭线程池
				System.out.println("ThreadPoolExecutorTest.main()");
				executorTest.shutdown();
				flag = false;
			}
		}
	}
	

	public ThreadPoolExecutorTest(int corePoolSize, int maximumPoolSize,
			long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue) ;
	}
	
	@Override
	protected void afterExecute(Runnable r, Throwable t) { // 对 ThreadPoolExecutor进行扩展
		super.afterExecute(r, t); // 在方法体开始的地方调用父类方法
		System.out.println("ThreadPoolExecutorTest.afterExecute()");
	}
	@Override
	protected void beforeExecute(Thread t, Runnable r) { // 对 ThreadPoolExecutor进行扩展
		System.out.println("ThreadPoolExecutorTest.beforeExecute()"); 
		super.beforeExecute(t, r); // 在方法体结尾的地方调用父类方法
	}
	@Override
	protected void terminated() { // 对 ThreadPoolExecutor进行扩展,线程池关闭之后执行
		super.terminated();
		System.out.println("ThreadPoolExecutorTest.terminated()"); // 进行收尾操作
	}

}

class MyThreadFactory implements ThreadFactory{
	@Override
	public Thread newThread(Runnable r) {
		System.out.println("MyThreadFactory.newThread()");
		return new MyThread();
	}
}

class MyThread extends Thread{
	@Override
	public void run() {
		try {
			Thread.sleep(2000); // 设置任务的处理时长,时间长的任务,可以顺序看到创建线程数量超过maxnuimPoolSize并且队列没有多余空间时,进行拒绝策略处理,默认为抛出异常
			System.out.println(Thread.currentThread().getName()+",sleep 2000ms");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class MyRejectedExecutionHandler implements RejectedExecutionHandler {
	@Override
	public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
		System.out.println("MyRejectedExecutionHandler.rejectedExecution()");
	}
}

打印结果:

触发拒绝策略时,不影响已提交的任务的处理:

ThreadPoolExecutorTest.main() create thread index :1
ThreadPoolExecutorTest.main() create thread index :2
ThreadPoolExecutorTest.beforeExecute()
ThreadPoolExecutorTest.main() create thread index :3
ThreadPoolExecutorTest.beforeExecute()
ThreadPoolExecutorTest.main() create thread index :4
ThreadPoolExecutorTest.beforeExecute()
ThreadPoolExecutorTest.main() create thread index :5
ThreadPoolExecutorTest.main() create thread index :6
ThreadPoolExecutorTest.main() create thread index :7
ThreadPoolExecutorTest.main() create thread index :8
ThreadPoolExecutorTest.beforeExecute()
ThreadPoolExecutorTest.main() create thread index :9
ThreadPoolExecutorTest.beforeExecute()
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task Thread[Thread-8,5,main] rejected from com.geor.collection.ThreadPoolExecutorTest@7d6f77cc[Running, pool size = 5, active threads = 5, queued tasks = 3, completed tasks = 0]
	at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
	at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
	at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
	at com.geor.collection.ThreadPoolExecutorTest.main(ThreadPoolExecutorTest.java:28)
pool-1-thread-1,sleep 2000ms
ThreadPoolExecutorTest.afterExecute()
ThreadPoolExecutorTest.beforeExecute()
pool-1-thread-2,sleep 2000ms
ThreadPoolExecutorTest.afterExecute()
ThreadPoolExecutorTest.beforeExecute()
pool-1-thread-3,sleep 2000ms
ThreadPoolExecutorTest.afterExecute()
ThreadPoolExecutorTest.beforeExecute()
pool-1-thread-4,sleep 2000ms
ThreadPoolExecutorTest.afterExecute()
pool-1-thread-5,sleep 2000ms
ThreadPoolExecutorTest.afterExecute()
pool-1-thread-1,sleep 2000ms
ThreadPoolExecutorTest.afterExecute()
pool-1-thread-2,sleep 2000ms
ThreadPoolExecutorTest.afterExecute()
pool-1-thread-3,sleep 2000ms
ThreadPoolExecutorTest.afterExecute()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值