线程池原理
用来统一管理,分配,释放线程资源的自动化手段,作用是避免频繁创建线程带来的系统开销,发挥多线程对程序的优化作用。
一个完整的线程池应该具备一下参数:
- 任务队列
- 线程管理功能:初始化线程数量init、允许扩充的线程最大数量max、释放空闲连接时保证有一定数量的核心线程数量core
- 任务拒绝策略
- 线程工厂:用于个性化定制线程
- QueueSize:任务队列最大数
- Keepedalive时间:决定各个重要参数自动维护的时间间隔
代码实现
定义线程池接口
package myThreadPool;
/**
* @ClassName ThreadPool
* @Description 线程池接口
* @Author zhang
* @Date 2020/2/17 23:23
* @Version 1.0
**/
public interface ThreadPool {
//提交任务到线程池
void execute(Runnable runnable);
//关闭线程池
void shutdown();
//获取线程池初始化大小
int getInitSize();
//获取线程池最大线程数
int getMaxSize();
//获取线程池核心线程数
int getCoreSize();
//获取线程池任务队列大小
int getQueueSize();
//获取线程池活跃线程数量
int getActiveCount();
//查看线程池是否已经被shutdown
boolean isShutdown();
}
定义任务队列接口
package myThreadPool;
/**
* @ClassName RunnableQueue
* @Description 任务队列接口
* @Author zhang
* @Date 2020/2/17 23:36
* @Version 1.0
**/
public interface RunnableQueue {
//当有新的任务进来时首先会offer到队列中
void offer(Runnable runnable);
//工作线程通过take获取Runnable
Runnable take();
//获取任务队列中任务的数量
int size();
}
定义创建线程的工厂,以便于个性化定制Thread
package myThreadPool;
/**
* @ClassName ThreadFactory
* @Description 创建线程的接口
* @Author zhang
* @Date 2020/2/17 23:43
* @Version 1.0
**/
@FunctionalInterface
public interface ThreadFactory {
Thread createThread(Runnable runnable);
}
定义饱和策略接口,默认三种实现
package myThreadPool;
/**
* @ClassName DenyPolicy
* @Description 饱和策略接口
* @Author zhang
* @Date 2020/2/17 23:47
* @Version 1.0
**/
@FunctionalInterface
public interface DenyPolicy {
//拒绝接口
void reject(Runnable runnable,ThreadPool threadPool);
//1.直接丢弃任务
class DiscardDenyPolicy implements DenyPolicy{
@Override
public void reject(Runnable runnable, ThreadPool threadPool) {
//do nothing
}
}
//2.向任务提交者抛出异常
class AbortdDenyPolicy implements DenyPolicy{
@Override
public void reject(Runnable runnable, ThreadPool threadPool) {
throw new RunnableDenyException("The runnable "+runnable+" will be abort");
}
}
//3.使任务在提交者所在的线程执行
class RunnerDenyPolicy implements DenyPolicy{
@Override
public void reject(Runnable runnable, ThreadPool threadPool) {
if(!threadPool.isShutdown()){
runnable.run();
}
}
}
}
定义一个异常类,主要用于返回给提交者异常(无法执行任务)
package myThreadPool;
/**
* @ClassName RunnableDenyException
* @Description 异常类
* @Author zhang
* @Date 2020/2/18 0:03
* @Version 1.0
**/
public class RunnableDenyException extends RuntimeException {
public RunnableDenyException(String message) {
super(message);
}
}
定义一个线程池内部控制线程
package myThreadPool;
/**
* @ClassName InternalTask
* @Description TODO
* @Author zhang
* @Date 2020/2/18 0:06
* @Version 1.0
**/
public class InternalTask implements Runnable {
private final RunnableQueue runnableQueue;
//开关,用于停止当前线程,一般在线程池销毁或者线程数量维护时会使用到
private volatile boolean running=true;
public InternalTask(RunnableQueue runnableQueue) {
this.runnableQueue = runnableQueue;
}
@Override
public void run() {
//如果当前任务为running并且没有被中断,则将其不断从queue中获取runnable,然后执行
while(running&&!Thread.currentThread().isInterrupted()){
Runnable task= runnableQueue.take();
task.run();
}
//如果isInterrupted为true,说明此线程为中断,此时关闭开关状态
running=false;
}
//停止当前任务,主要会在线程池的shutdown方法中使用
public void stop(){
this.running=false;
}
}