自定义线程是为了练习,对前面的学习进行汇总,JDK的ExecutorService线程池的实现已经很够用了。
一个完整线程池具备的要素
- 任务队列:用于缓存提交的任务。
- 线程数量管理功能:线程池必须能够很好的管理自己的线程数量,线程自动扩充时的最大线程数量,空闲时也要维护的核心线程数量。
- 任务拒绝策略:线程数量已达上限并且任务队列已满,则需要有相应的拒绝策略来通知任务提交者。
- 线程工厂:主要用于个性定制线程,比如设置线程为守护线程,以及设置线程名称等。
- QueueSize:任务队列主要存放提交的Runnable.
- keepedalive时间:决定线程各个参数自动维护的时间间隔。
UML类图
ThreadPoolP 接口
public interface ThreadPoolP {
/**
*
* @Title execute
* @param runnabel
* @Description 提交任务到线程池
* @throws
*/
void execute(Runnable runnable);
/**
*
* @Title shutdown
* @Description 关闭线程池
* @throws
*/
void shutdown();
/**
*
* @Title getInitSize
* @return
* @Description 获取线程池初始化大小
* @throws
*/
int getInitSize();
/**
*
* @Title getMaxSize
* @return
* @Description 获取线程池最大线程数
* @throws
*/
int getMaxSize();
/**
*
* @Title getCoreSize
* @return
* @Description 获取核心线程数
* @throws
*/
int getCoreSize();
/**
*
* @Title getQueueSize
* @return
* @Description 获取线程池中缓存队列大小
* @throws
*/
int getQueueSize();
/**
*
* @Title getActiveCount
* @return
* @Description 获取线程池中活跃线程数量
* @throws
*/
int getActiveCount();
/**
*
* @Title isShutdown
* @return
* @Description 查看线程池是否关闭
* @throws
*/
boolean isShutdown();
}
DenyPolicyP 接口
@FunctionalInterface
public interface DenyPolicyP {
/**
*
* @Title reject
* @param runnable
* @param threadFactoryP
* @Description 拒绝策略方法
* @throws
*/
void reject(Runnable runnable,ThreadPoolP threadPoolP);
class DiscardDenyPolicyP implements DenyPolicyP{
@Override
public void reject(Runnable runnable, ThreadPoolP threadPoolP) {
// TODO Auto-generated method stub
System.out.println(" DiscardDenyPolicyP 直接放弃任务");
}
}
class AbortDenyPolicyP implements DenyPolicyP{
@Override
public void reject(Runnable runnable, ThreadPoolP threadPoolP) {
System.out.println("AbortDenyPolicyP 队列已满,添加任务失败");
throw new RunnableDenyExceptionP("队列已满,添加任务失败");
}
}
class RunnerDenyPolicyP implements DenyPolicyP{
@Override
public void reject(Runnable runnable, ThreadPoolP threadPoolP) {
if(!threadPoolP.isShutdown()) {
System.out.println("RunnerDenyPolicyP 在提交者的线程中执行");
runnable.run();
}
}
}
}
RunnableQueueP 接口
public interface RunnableQueueP {
/**
*
* @Title offer
* @param runnable
* @Description 新任务进来时添加到队列中
* @throws
*/
void offer(Runnable runnable);
/**
*
* @Title task
* @return
* @Description 取出队列中得任务
* @throws
*/
Runnable task() throws InterruptedException;
/**
*
* @Title size
* @return
* @Description 获取任务队列大小
* @throws
*/
int size();
}
ThreadFactoryP 接口
@FunctionalInterface
public interface ThreadFactoryP {
/**
*
* @Title createThread
* @param runnable
* @return
* @Description 创建线程
* @throws
*/
Thread createThread(Runnable runnable);
}
InternalTaskP
public class InternalTaskP implements Runnable{
private final RunnableQueueP runnableQueueP;
private volatile boolean running =true;
public InternalTaskP(RunnableQueueP runnableQueueP) {
this.runnableQueueP = runnableQueueP;
}
@Override
public void run() {
//线程没有中断,则不断从队列中取出Runnable,执行run方法
while(running && !Thread.currentThread().isInterrupted() ) {
try {
Runnable task = runnableQueueP.task();
task.run();
} catch (InterruptedException e) {
running =false;
break;
}
}
}
//停止当前任务
public void stop() {
this.running = false;
}
}
RunnableDenyExceptionP
public class RunnableDenyExceptionP extends RuntimeException{
public RunnableDenyExceptionP(String msg) {
super(msg);
}
}
LinkedRunnableQueueP
public class LinkedRunnableQueueP implements RunnableQueueP{
//任务队列最大容量
private final int maxSize;
//拒绝策略
private final DenyPolicyP denyPolicyP;
//任务队列
private final LinkedList<Runnable> runList = new LinkedList<Runnable>();
private final ThreadPoolP threadPoolP;
public LinkedRunnableQueueP(int maxSize, DenyPolicyP denyPolicyP, ThreadPoolP threadPoolP) {
this.maxSize = maxSize;
this.denyPolicyP = denyPolicyP;
this.threadPoolP = threadPoolP;
}
@Override
public void offer(Runnable runnable) {
synchronized (runList) {
if(runList.size()>=maxSize) {
//任务队列满,执行拒绝策略
System.out.println(Thread.currentThread().getName()+" 队列满执行拒绝策略 "+ threadPoolP.getQueueSize());
denyPolicyP.reject(runnable, threadPoolP);
}else {
//将任务队列添加到队尾,并且唤醒线程
runList.addLast(runnable);
runList.notifyAll();
}
}
}
@Override
public Runnable task() throws InterruptedException{
synchronized (runList) {
while(runList.isEmpty()) {
try {
//任务队列为空则将线程挂起
runList.wait();
} catch (InterruptedException e) {
throw e;
}
}
//从队列头部移除一个任务
return runList.removeFirst();
}
}
@Override
public int size() {
synchronized (runList) {
return runList.size();
}
}
}
BasicThreadPoolP
public class BasicThreadPoolP extends Thread implements ThreadPoolP{
//初始化线程数量
private final int initSize;
//线程池最大线程数量
private final int maxSize;
//核心线程数
private final int coreSize;
//活跃线程数
private int activeCount;
//线程工厂
private final ThreadFactoryP threadFactory;
//任务队列
private final RunnableQueueP runnableQueue;
//线程是否被关闭
private volatile boolean isShutdown = false;
//工作线程队列
private final Queue<ThreadTask> threadQueue = new ArrayDeque<ThreadTask>();
//默认拒绝策略
private final static DenyPolicyP DEFAULT_DENY_POLICYP = new DenyPolicyP.DiscardDenyPolicyP();
//默认线程工厂
private final static ThreadFactoryP DEFAULT_THREAD_FACTORY = new DefualThreadFactory();
//线程空闲时间
private final long keepAliveTime;
//时间单位
private final TimeUnit timeUnit;
//线程空闲时间后销毁线程池 (队列无任务时间)
private final long destoryTime;
//默认销毁时间
private final static long DESTORY_TIME = 300000;
public BasicThreadPoolP(int initSize, int maxSize, int coreSize, int queueSize ) {
this(initSize,maxSize,coreSize,DEFAULT_THREAD_FACTORY,queueSize,
DEFAULT_DENY_POLICYP,10,TimeUnit.SECONDS,DESTORY_TIME);
}
public BasicThreadPoolP(int initSize, int maxSize, int coreSize, int queueSize ,DenyPolicyP denyPolicyP) {
this(initSize,maxSize,coreSize,DEFAULT_THREAD_FACTORY,queueSize,
denyPolicyP,10,TimeUnit.SECONDS,DESTORY_TIME);
}
public BasicThreadPoolP(int initSize, int maxSize, int coreSize, int queueSize ,long destoryTime) {
this(initSize,maxSize,coreSize,DEFAULT_THREAD_FACTORY,queueSize,
DEFAULT_DENY_POLICYP,10,TimeUnit.SECONDS,destoryTime);
}
public BasicThreadPoolP(int initSize, int maxSize, int coreSize, ThreadFactoryP threadFactory,
int queueSize, DenyPolicyP denyPolicyP,long keepAliveTime, TimeUnit timeUnit,long destoryTime) {
this.initSize = initSize;
this.maxSize = maxSize;
this.coreSize = coreSize;
this.threadFactory = threadFactory;
this.runnableQueue = new LinkedRunnableQueueP(queueSize, denyPolicyP, this);
this.keepAliveTime = keepAliveTime;
this.timeUnit = timeUnit;
this.destoryTime=destoryTime;
this.init();
}
private void init() {
start();
for(int i=0;i<initSize;i++) {
newThread();
}
}
private void newThread() {
InternalTaskP internalTaskP = new InternalTaskP(runnableQueue);
Thread thread = this.threadFactory.createThread(internalTaskP);
ThreadTask threadTask = new ThreadTask(thread, internalTaskP);
threadQueue.offer(threadTask);
this.activeCount++;
thread.start();
}
private void removeThread() {
ThreadTask threadTask = threadQueue.remove();
threadTask.internalTaskP.stop();
this.activeCount--;
}
@Override
public void run() {
//用于维护线程数量,扩容,回收等工作
while(!isShutdown && !isInterrupted()) {
try {
timeUnit.sleep(keepAliveTime);
} catch (InterruptedException e) {
isShutdown=true;
break;
}
synchronized (this) {
if(isShutdown) {
break;
}
//当前队列中有任务未处理,并且activeCount<coreSize则扩容
if(runnableQueue.size()>0&&activeCount<coreSize) {
for(int i=initSize;i<coreSize;i++) {
System.out.println("activeCount<coreSize则扩容");
newThread();
}
//不想让线程的扩容直接到最大
continue;
}
//当前队列中有任务未处理,并且activeCount<maxSize则继续扩容
if(runnableQueue.size()>0&&activeCount<maxSize) {
for(int i=coreSize;i<maxSize;i++) {
System.out.println("activeCount<maxSize则继续扩容");
newThread();
}
}
//当前队列中没有任务,则需要回收到coreSize
if(runnableQueue.size()==0&&activeCount>coreSize) {
for(int i=coreSize;i<activeCount;i++) {
System.out.println("当前队列中没有任务,则需要回收到coreSize");
removeThread();
}
}
}
}
}
@Override
public void execute(Runnable runnable) {
if(this.isShutdown) {
throw new IllegalStateException("Thread pool destory");
}
this.runnableQueue.offer(runnable);
}
@Override
public void shutdown() {
synchronized (this) {
if(isShutdown) {
return ;
}else {
isShutdown = true;
threadQueue.forEach(threadTask->{
threadTask.internalTaskP.stop();
threadTask.thread.interrupt();
});
this.interrupt();
System.out.println("线程此销毁完毕");
}
}
}
@Override
public int getInitSize() {
if(this.isShutdown) {
throw new IllegalStateException("Thread pool destory");
}
return this.initSize;
}
@Override
public int getMaxSize() {
if(this.isShutdown) {
throw new IllegalStateException("Thread pool destory");
}
return this.maxSize;
}
@Override
public int getCoreSize() {
if(this.isShutdown) {
throw new IllegalStateException("Thread pool destory");
}
return this.coreSize;
}
@Override
public int getQueueSize() {
if(this.isShutdown) {
throw new IllegalStateException("Thread pool destory");
}
return this.runnableQueue.size();
}
@Override
public int getActiveCount() {
synchronized (this) {
return this.activeCount;
}
}
@Override
public boolean isShutdown() {
return this.isShutdown;
}
private static class DefualThreadFactory implements ThreadFactoryP{
private static final AtomicInteger GROPU_COUNTER = new AtomicInteger();
private static final ThreadGroup group =
new ThreadGroup("my_thread_pool-"+GROPU_COUNTER.getAndDecrement());
private static final AtomicInteger COUNTER = new AtomicInteger(0);
@Override
public Thread createThread(Runnable runnable) {
return new Thread(group,runnable,"thread-pool-p"+COUNTER.getAndDecrement());
}
}
private static class ThreadTask{
Thread thread;
InternalTaskP internalTaskP;
public ThreadTask(Thread thread,InternalTaskP internalTaskP) {
this.thread =thread;
this.internalTaskP = internalTaskP;
}
}
}
ThreadPoolPTest
public static void main(String[] args) {
//初始化线程数2,核心 4,最大6,队列最大任务100, 默认放弃任务策略
final ThreadPoolP threadPoolP = new BasicThreadPoolP(2,6,4,100,50);
//初始化线程数2,核心 4,最大6,队列最大任务100,抛出异常
//final ThreadPoolP threadPoolP = new BasicThreadPoolP(2,6,4,100,new DenyPolicyP.AbortDenyPolicyP());
//初始化线程数2,核心 4,最大6,队列最大任务100,在提交者的线程中执行
//final ThreadPoolP threadPoolP = new BasicThreadPoolP(2,6,4,100,new DenyPolicyP.RunnerDenyPolicyP());
for(int i=0;i<110;i++) {
threadPoolP.execute(()->{
try {
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName()+"在运行中");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
}
while(!threadPoolP.isShutdown()) {
System.out.println("getActiveCount :"+threadPoolP.getActiveCount());
System.out.println("getQueueSize :"+threadPoolP.getQueueSize());
System.out.println("getCoreSize :"+threadPoolP.getCoreSize());
System.out.println("getMaxSize :"+threadPoolP.getMaxSize());
try {
TimeUnit.SECONDS.sleep(8);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出
main 队列满执行拒绝策略 100
DiscardDenyPolicyP 直接放弃任务
main 队列满执行拒绝策略 100
DiscardDenyPolicyP 直接放弃任务
main 队列满执行拒绝策略 100
…
getActiveCount :2
getQueueSize :100
getCoreSize :4
getMaxSize :6
thread-pool-p0在运行中
thread-pool-p-1在运行中
thread-pool-p0在运行中
…
activeCount<coreSize则扩容
activeCount<coreSize则扩容
…
getActiveCount :4
getQueueSize :56
getCoreSize :4
getMaxSize :6
…
activeCount<maxSize则继续扩容
activeCount<maxSize则继续扩容
…
getActiveCount :6
getQueueSize :14
getCoreSize :4
getMaxSize :6
…
当前队列中没有任务,则需要回收到coreSize
getActiveCount :5
getQueueSize :0
getCoreSize :4
getMaxSize :6
当前队列中没有任务,则需要回收到coreSize
getActiveCount :4
getQueueSize :0
getCoreSize :4
getMaxSize :6
第一次扩容线程
第二次扩容线程