我们并不是要闭门造车,因为现在市面上有一些非常优秀的线程池供我们使用,我们写这段代码的目的是为了更好的理解和使用线程池。
首先说一说一个线程池应该具备哪些东西
1 初始化线程个数
2核心线程个数
3最大线程个数
4维护线程池中线程数量,当线程空闲数多时尽心线程的回收,当线程紧张时进行线程的创建
5任务添加策略
6任务队列
7线程的构造工厂
我们有这些基本就算是够了
现在我们先来定义接口
/**
* 线程池的接口
* @author 魏金浩
*
*/
public interface ThreadPool {
/*
* 提交任务到线程池
*/
public void execute(Runnable runnable) throws Exception;
/**
* 关闭线程池
*/
public void shutdown();
/**
* 判断当前线程池是否被关闭
* @return 线程池的关闭状态
*/
public boolean isShutdown();
/**
* 获取线程池的最大数
* @return 线程池的最大数
*/
public int getMaxSize();
/**
* 获取线程池的初始化大小
* @return 线程池的初始化大小
*/
public int getInitSize();
/**
* 获取线程池的核心线程数
* @return 获取线程池的核心线程数
*/
public int getCoreSize();
/**
* 获取线程池的活跃线程数
* @return 获取线程池的活跃线程数
*/
public int getActiveSize();
/**
* 获取任务队列的大小
* @return 任务队列的大小
*/
public int getQueueSize();
}
/**
* 构造线程的工厂
* @author 魏金浩
*
*/
public interface ThreadFactory {
/**
* 根据runnable去创建线程
* @param runnable 根据他去创建线程
* @return 创建的线程
*/
Thread createThread(Runnable runnable);
}
/**
* 任务队列
* @author 魏金浩
*
*/
public interface RunnableQueue {
/**
* 将任务提交到任务队列中
* @param runnable 用户提交的任务
*/
public void offer(Runnable runnable);
/**
* 供工作线程使用从队列中获取Runnable
* @return 从队列中获取Runnable
* @throws InterruptedException
*/
public Runnable take() throws InterruptedException;
/**
* 获取任务队列中任务的数量
* @return 任务队列中任务的数量
*/
public int size();
}
/**
* 当任务队列满时的拒绝策略
* @author 魏金浩
*
*/
public interface DenyPolicy {
public void reject(Runnable runnable ,ThreadPool pool);
//该拒绝策略将会直接丢弃任务
class DiscardDenyPolicy implements DenyPolicy {
@Override
public void reject(Runnable runnable, ThreadPool pool) {
}
}
//该拒绝策略会抛出异常
class AbortDenyPolicy implements DenyPolicy {
@Override
public void reject(Runnable runnable, ThreadPool pool) {
throw new DenyRunnableException("the runnable" + runnable + "will be abort.");
}
}
//该拒绝策略会在用户的工作线程中执行任务
class RunnerDenyPolicy implements DenyPolicy {
@Override
public void reject(Runnable runnable, ThreadPool pool) {
if(pool.isShutdown() != true) {
runnable.run();
}
}
}
}
上面的任务添加策略中我们在其内部实现了三个策略,详细的作用已经进行了标注
剩下的任务就是进行接口的实现了
任务队列的实现
public class LinkedRunnableQueue implements RunnableQueue{
//任务添加策略
private DenyPolicy denyPolicy;
//存放任务的容器
private LinkedList<Runnable> queue;
//存放任务的最大个数
private int limit;
//供我们的任务添加策略使用
private ThreadPool pool;
public LinkedRunnableQueue(DenyPolicy denyPolicy ,int limit ,ThreadPool pool) {
super();
this.denyPolicy = denyPolicy;
this.queue = new LinkedList<>();
this.limit = limit;
this.pool = pool;
}
@Override
public void offer(Runnable runnable) {
synchronized (queue) {
if(queue.size() >= limit) {
denyPolicy.reject(runnable, pool);
}
else {
queue.addLast(runnable);
queue.notifyAll();
}
}
}
@Override
public Runnable take() throws InterruptedException {
synchronized (queue) {
while (queue.size() ==0) {
try {
queue.wait();
} catch (InterruptedException e) {
throw e;
}
}
Runnable first = queue.removeFirst();
return first;
}
}
@Override
public int size() {
synchronized (queue) {
return queue.size();
}
}
}
任务添加策略所需要的异常类
public class DenyRunnableException extends RuntimeException{
public DenyRunnableException(String message) {
super(message);
}
}
/**
* 用于线程池内部作用是去在任务队列中去任务
* @author 魏金浩
*
*/
public class InternalTask implements Runnable{
private final RunnableQueue runnableQueue;
private boolean running = true;
public InternalTask(RunnableQueue runnableQueue) {
this.runnableQueue = runnableQueue;
}
public void stop() {
this.running = false;
}
//他的作用就是不断的从任务队列中进行取出,并执行任务的run方法
@Override
public void run() {
while(running != false && Thread.currentThread().isInterrupted() != true) {
try {
Runnable runnable = runnableQueue.take();
runnable.run();
}catch ( InterruptedException e) {
this.running = false;
break;
}
}
}
}
public class BaiscThreadPool extends Thread implements ThreadPool{
private int maxSize;
private int coreSize;
private int initSize;
private int activeAccount;
private boolean shutdown = false;
private RunnableQueue runnableQueue;
private Queue<ThreadTask> queue;
private DenyPolicy denyPolicy;
private ThreadFactory threadFactory;
private long keepAliveTime;
private TimeUnit timeUnit;
private static DenyPolicy DEFAULT_DENYPOLICY = new DenyPolicy.DiscardDenyPolicy();
private static ThreadFactory DEFAULT_THREADFACTORY = new BaiscThreadPool.DefaultThreadFactory();
//因为线程池的构造函数过于复杂所以我们就从抽取出了几个重要的参数进行用户设定,剩下的使用默认
//值
public BaiscThreadPool(int maxSize, int coreSize, int initSize,int queueSize) {
this(maxSize,coreSize,initSize,10,TimeUnit.SECONDS,queueSize);
}
private BaiscThreadPool(int maxSize, int coreSize, int initSize,
long keepAliveTime,TimeUnit timeUnit,int queueSize) {
super();
this.maxSize = maxSize;
this.coreSize = coreSize;
this.initSize = initSize;
this.runnableQueue = new LinkedRunnableQueue(DEFAULT_DENYPOLICY,queueSize,this);
this.queue = new ArrayDeque<>();
this.keepAliveTime = keepAliveTime;
this.timeUnit = timeUnit;
this.threadFactory=this.DEFAULT_THREADFACTORY;
//调用init函数开启维护线程池线程的线程,并先初始化一定数量的线程
this.init();
}
private void init() {
//开启线程池的维护线程
start();
//初始化一定数量的线程
for(int i = 0;i < this.initSize;i++) {
newThread();
}
}
//在线程池中创建工作线程
private void newThread() {
//这是一个Runnable的实现类,他的run方法就是不断的从this.runnableQueue 任务队列中读取任
//务,并执行run
InternalTask internalTask = new InternalTask(this.runnableQueue);
Thread thread = this.threadFactory.createThread(internalTask);
ThreadTask threadTask = new ThreadTask(thread,internalTask);
queue.offer(threadTask);
this.activeAccount ++;
//开启线程
thread.start();
}
//从线程池中删除工作线程
private void removeThread() {
ThreadTask threadTask = queue.remove();
threadTask.internalTask.stop();
this.activeAccount --;
}
//这是我们的thread的run方法,他的作用是当维护线程池的稳定,当线程不够使用时创建线程,当线程
//空闲数多时回收线程
@Override
public void run() {
while(this.shutdown != true && !this.isInterrupted()) {
try {
timeUnit.sleep(keepAliveTime);
} catch (InterruptedException e) {
this.shutdown = true;
break;
}
synchronized (this) {
if(this.shutdown) {
break;
}
//当前任务中有任务没有处理,并且当前线程数没有达到核心线程数,创建线程
if(this.runnableQueue.size() >0 && this.activeAccount < this.coreSize) {
for (int i = this.activeAccount; i < this.coreSize; i++) {
newThread();
}
continue;
}
//当前任务中有任务没有处理,并且当前线程数没有达到上限,创建线程
if(this.runnableQueue.size() > 0 && this.activeAccount < this.maxSize) {
for (int i = this.activeAccount; i < this.maxSize; i++) {
newThread();
}
}
//当前任务队列中没有任务要处理,进行线程的回收,回收到核心线程数即可
if(this.runnableQueue.size() == 0 && this.activeAccount > this.coreSize) {
for (int i = this.coreSize; i < this.activeAccount; i++) {
removeThread();
}
}
}
}
}
//将我们要执行的任务添加到任务队列中去
@Override
public void execute(Runnable runnable) throws Exception {
if(this.shutdown ==false) {
this.runnableQueue.offer(runnable);
}else {
throw new Exception("thread pool is destory.");
}
}
//关闭线程池
@Override
public void shutdown() {
synchronized (this) {
if(this.shutdown) {
return ;
}
this.shutdown = true;
this.queue.forEach((threadTask) -> {
threadTask.internalTask.stop();
threadTask.thread.interrupt();
});
this.interrupt();
}
}
@Override
public boolean isShutdown() {
return this.shutdown;
}
@Override
public int getMaxSize() {
return this.maxSize;
}
@Override
public int getInitSize() {
return this.initSize;
}
@Override
public int getCoreSize() {
return this.coreSize;
}
@Override
public int getActiveSize() {
return this.activeAccount;
}
@Override
public int getQueueSize() {
return this.runnableQueue.size();
}
public class ThreadTask {
private Thread thread;
private InternalTask internalTask;
public ThreadTask(Thread thread, InternalTask internalTask) {
super();
this.thread = thread;
this.internalTask = internalTask;
}
}
//我们自定义的创建线程的工厂,实际上new Thread()函数会更为复杂
static public class DefaultThreadFactory implements ThreadFactory{
@Override
public Thread createThread(Runnable runnable) {
return new Thread(runnable);
}
}
}