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

被折叠的 条评论
为什么被折叠?



