自定义线程池
Posted ylz8401
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义线程池相关的知识,希望对你有一定的参考价值。
转自:https://www.cnblogs.com/nele/p/6502750.html
线程池执行的流程:
当任务提交给ThreadPoolExecutor 线程池中,先检查核心线程数是否已经全部使用,
如果没有交由核心线程去执行任务,
如果核心线程数已经全部占用,则将任务添加到队列里面,
如果队列已经占满,比较当前线程池的中线程的数量是不是与超过maximumPoolSize,如果没有查过则创建线程去执行。
也就是说线程池最多可以接受多少任务呢?就是maximumPoolSize+队列的大小。
当线程池中的线程的数量大于corePoolSize数量有空闲线程则执行回收,回收时间是keepAliveTime,单位是unit,都是初始化的时候设置的。
下面通过代码来说明:
定义一个实现了Runnable接口的类,当作任务类:
package com.ctrip.ck.test.thread.pool; public class MyTask implements Runnable { private int taskId; private String taskName; public MyTask(int taskId, String taskName) { this.taskId = taskId; this.taskName = taskName; } //getter/setter public int getTaskId() { return taskId; } public void setTaskId(int taskId) { this.taskId = taskId; } public String getTaskName() { return taskName; } public void setTaskName(String taskName) { this.taskName = taskName; } @Override public void run() { System.out.println("taskId:" + taskId + ",taskName:" + taskName); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } }
定义如下的线程池:
private static ThreadPoolExecutor pool = new ThreadPoolExecutor(// 自定义一个线程池
1, // coreSize
2, // maxSize
60, // 60s
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3), // 有界队列,容量是3个
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
测试类:
1 import java.util.concurrent.ArrayBlockingQueue; 2 import java.util.concurrent.Executors; 3 import java.util.concurrent.ThreadPoolExecutor; 4 import java.util.concurrent.TimeUnit; 5 6 public class PoolTest { 7 private static ThreadPoolExecutor pool = new ThreadPoolExecutor(// 自定义一个线程池 8 1, // coreSize 9 2, // maxSize 10 60, // 60s 11 TimeUnit.SECONDS, 12 new ArrayBlockingQueue<>(3), // 有界队列,容量是3个 13 Executors.defaultThreadFactory(), 14 new ThreadPoolExecutor.AbortPolicy() 15 ); 16 17 public static void main(String[] args) { 18 pool.execute(new MyTask(1, "任务1")); 19 System.out.println("活跃的线程数:" + pool.getActiveCount() + ",核心线程数:" + pool.getCorePoolSize() + ",线程池大小:" + pool.getPoolSize() + ",队列的大小" + pool.getQueue().size()); 20 21 pool.execute(new MyTask(2, "任务2")); 22 System.out.println("活跃的线程数:" + pool.getActiveCount() + ",核心线程数:" + pool.getCorePoolSize() + ",线程池大小:" + pool.getPoolSize() + ",队列的大小" + pool.getQueue().size()); 23 24 pool.execute(new MyTask(3, "任务3")); 25 System.out.println("活跃的线程数:" + pool.getActiveCount() + ",核心线程数:" + pool.getCorePoolSize() + ",线程池大小:" + pool.getPoolSize() + ",队列的大小" + pool.getQueue().size()); 26 27 pool.execute(new MyTask(4, "任务4")); 28 System.out.println("活跃的线程数:" + pool.getActiveCount() + ",核心线程数:" + pool.getCorePoolSize() + ",线程池大小:" + pool.getPoolSize() + ",队列的大小" + pool.getQueue().size()); 29 30 pool.execute(new MyTask(5, "任务5")); 31 System.out.println("活跃的线程数:" + pool.getActiveCount() + ",核心线程数:" + pool.getCorePoolSize() + ",线程池大小:" + pool.getPoolSize() + ",队列的大小" + pool.getQueue().size()); 32 33 pool.execute(new MyTask(6, "任务6")); 34 System.out.println("活跃的线程数:" + pool.getActiveCount() + ",核心线程数:" + pool.getCorePoolSize() + ",线程池大小:" + pool.getPoolSize() + ",队列的大小" + pool.getQueue().size()); 35 36 pool.shutdown(); 37 System.out.println("------ over ------"); 38 } 39 40 }
运行结果:
1 活跃的线程数:1,核心线程数:1,线程池大小:1,队列的大小0 2 活跃的线程数:1,核心线程数:1,线程池大小:1,队列的大小1 3 taskId:1,taskName:任务1 4 活跃的线程数:1,核心线程数:1,线程池大小:1,队列的大小2 5 活跃的线程数:1,核心线程数:1,线程池大小:1,队列的大小3 6 活跃的线程数:2,核心线程数:1,线程池大小:2,队列的大小3 7 Exception in thread "main" taskId:5,taskName:任务5 8 java.util.concurrent.RejectedExecutionException: Task com.ctrip.ck.test.thread.pool.MyTask@3532ec19 rejected from java.util.concurrent.ThreadPoolExecutor@68c4039c[Running, pool size = 2, active threads = 2, queued tasks = 3, completed tasks = 0] 9 at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047) 10 at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823) 11 at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369) 12 at com.ctrip.ck.test.thread.pool.PoolTest.main(PoolTest.java:36) 13 taskId:2,taskName:任务2 14 taskId:3,taskName:任务3 15 taskId:4,taskName:任务4
以上是关于自定义线程池的主要内容,如果未能解决你的问题,请参考以下文章