我这里通过看书学习到一篇线程池的原理,以及去自己定义线程池,对线程池的理解还是增加不少,在此记录一下。
首先得理解什么是线程池,简单来说,就是一个池子里边存放着一些已经创建好的线程,有任务提交过来,启用池子里的某个线程去执行此任务。
但是还有一些问题,就是如果池子中的线程数量不够应付太多的任务时,则需要去自动向池子里增加一些新的线程,但是也不能是无限增加的。如果任务比较少的话,那也不能让太多的资源浪费,就得自动回收一些线程。为了能异步地提交任务和缓存没有被处理的任务,还需要有一个任务队列。
所以,线程池需要有:
- 任务队列:用于缓存提交的任务
- 三个参数控制线程数量:初始数量,最大线程数量,核心数量。
- 拒绝策略:线程数量达到上限并且任务队列已满,则需要有相应的策略
- 任务队列中也需要一个限制提交任务数量
- 参数维护时间间隔
知道个大概就可以开始动手了
先写线程池接口
**
* 自定义线程池接口
* @Author: hasaki_w_c
* @Date:2021/9/29 下午7:35
*/
public interface MyThreadPool {
/**
* 提交任务到线程池
* @param runnable Runnable 线程
*/
void execute(Runnable runnable);
/**
* 关闭线程池
*/
void shutdown();
/**
* 获取线程池初始化大小
* @return 线程池初始数量
*/
int getInitSize();
/**
* 获取线程池最大的线程数
* @return 线程池最大线程数
*/
int getMaxSize();
/**
* 获取线程池的核心线程数量
* @return 线程池但核心线程数量
*/
int getCoreSize();
/**
* 获取线程池中用于缓存任务队列的大小
* @return 线程池中任务队列的大小
*/
int getQueueSize();
/**
* 获取线程池中活跃线程的数量
* @return 线程池中活跃线程的数量
*/
int getActiveCount();
/**
* 查看线程池是否已经被 shutdown
* @return 线程时是否被 shutdown
*/
boolean isShutdown();
}
任务队列接口
/**
* 任务队列,用于缓存提交到线程池里的任务
* @Author: hasaki_w_c
* @Date:2021/9/29 下午7:48
*/
public interface MyRunnableQueue {
/**
* 当有新的任务进来时首先会 offer 到队列中
* @param runnable runnable 线程任务
*/
void offer(Runnable runnable);
/**
* 工作线程通过 take 方法获取 Runnable
* @return runnable 线程
*/
Runnable take() throws InterruptedException;
/**
* 获取任务队列中任务的数量
* @return 队列中任务但数量
*/
int size ();
}
线程创建的接口
/**
* 线程创建的接口
* @Author: hasaki_w_c
* @Date:2021/10/8 下午4:38
*/
@FunctionalInterface
public interface ThreadFactory {
/**
* 用于创建线程
* @param runnable runnable 对象
* @return Thread 线程
*/
Thread createThread(Runnable runnable);
}
拒绝策略接口
import myThreadPool.Exception.RunnableDenyException;
/**
* 自定义线程池的拒绝策略,当线程队列中的 runnable达到 limit 上限时,决定采用哪一种策略.
* @Author: hasaki_w_c
* @Date:2021/10/8 下午5:05
*/
public interface DenyPolicy {
/**
* 拒绝方法
* @param runnable runnable 线程对象
* @param myThreadPool 线程池对象
*/
void reject(Runnable runnable, MyThreadPool myThreadPool);
/**
* 该拒绝策略会直接丢弃任务
*/
class DiscardDenyPolicy implements DenyPolicy {
@Override
public void reject(Runnable runnable, MyThreadPool myThreadPool) {
//do nothing
}
}
/**
* 该拒绝策略会向任务提交者抛出异常
*/
class AbortDenyPolicy implements DenyPolicy{
@Override
public void reject(Runnable runnable, MyThreadPool myThreadPool) {
throw new RunnableDenyException("The runnable" + runnable + " will be abort");
}
}
/**
* 该拒绝策略会使任务在提交者所在的线程中执行任务
*/
class RunnerDenyPolicy implements DenyPolicy{
@Override
public void reject(Runnable runnable, MyThreadPool myThreadPool) {
if (myThreadPool.isShutdown()) {
runnable.run();
}
}
}
}
拒绝策略里边的异常是自定义的异常
/**
* 自定义异常,主要用于通知任务提交者,任务队列无法再接受新的任务
* @Author: hasaki_w_c
* @Date:2021/10/8 下午5:10
*/
public class RunnableDenyException extends RuntimeException{
public RunnableDenyException(String message) {
super(message);
}
}
这里接口就写完了,可以开始写实现类了
先看任务队列的实现类