对于开启一个线程以及销毁一个线程需要消费很长的时间,为了节省时间当有任务出现时,直接获取一个线程然后执行任务即可
线程池的的理解:
一个工厂有 N个人在工作时,当来个很多的任务一开始先分给这N个人,当这个N个人都处于忙碌状态时,那么就将后面的任务使用缓存队列进行缓存,当缓存队列满了时,看时候再招聘一些临时工,来处理这些工作,如果招聘了临时工或者没有招聘,那么后面的任务该怎么处理,丢弃并抛出异常
corePoolSize:表示开始N的工人
BlockingQueue:缓冲队列
maxPoolSize:表示容许的最大工人数
问题来了如果监控哪些线程处于空闲,即 如何监控线程的状态呢?
这里采用的类似的生产者以及消费者的模式,线程池的execute的方法类似生产者,而线程池里面的线程处于消费者的地位,BlockingQueue处于缓冲队列的地位,当任务不是繁忙时1.临时工要解雇 2.工人是否要解雇看具体的配置
具体的实现如下所示:
package com.cn.Executor;
import java.util.HashSet;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
*
* 使用的是BlockingQueue 里面有一些方法
*
* 1.放入数据 offer(object):放入数据如果放入成功,则返回true,否则则返回false
* off(object,time,timeunit):在time个时间内放入object,如果放进去则返回true,否则则返回false;
* 以上的方式是不堵塞的 put(object)放入一个数据是堵塞的,
*
* 2.取出数据 poll(),取出数据,如果没有则返回null poll(time,timeunit),在这个时间内取出数据,如果没有则返回null
*
* take():是堵塞的取出数据,如果没有则会等待
*/
public class MyThreadPoolExecutor {
private final BlockingQueue
private final ReentrantLock mainLock = new ReentrantLock();
private final HashSet
private int corePoolSize;// 初始化的线程的个数
private int maxPoolSize;// 线程池的最大个数,当corePoolSize满了,而且BlockingQueue缓冲队列也满了,则初始化额外的线程,如果额外的线程达到上限,则任务丢弃
private int workPoolSize;// 正在工作的线程
private final boolean allowCoreThreadTimeOut;
private final long keepAliveTime;
private final TimeUnit timeUnit;
// /private int runState;
// private AtomicInteger ctl=new AtomicInteger(ctls(runState,0));
public MyThreadPoolExecutor(int corePoolSize, int maxPoolSize,
boolean allowCoreThreadTimeOut, long keepAliveTime,
TimeUnit timeUnit, BlockingQueue
this.workQueue = workQueue;
this.corePoolSize = corePoolSize;
this.maxPoolSize = maxPoolSize;
this.allowCoreThreadTimeOut = allowCoreThreadTimeOut;
this.keepAliveTime = keepAliveTime;
this.timeUnit = timeUnit;
}
public MyThreadPoolExecutor(BlockingQueue
int corePoolSize, int maxPoolSize) {
this(corePoolSize, maxPoolSize, false, 0l, TimeUnit.SECONDS, workQueue);
}
// 主要方法的实现
public void execute(Runnable task) {
if (task == null) {
throw new IllegalArgumentException("The parameter is not null");
}
Worker work = null;
mainLock.lock();
if (workPoolSize < corePoolSize) {// 创建线程进行执行
work = new Worker(task);
} else if (!workQueue.offer(task)) {// 放到缓存队列中
if (workPoolSize < maxPoolSize) {// 开启额外的线程的进行执行
work = new Worker(task);
} else {
throw new RuntimeException("The task was thowed");// 任务的抛弃策略,这里使用抛出异常,即这个任务无法处理
}
}
if (work != null) {
workers.add(work);
work.t.start();
workPoolSize++;
}
mainLock.unlock();
}
public void shutDownNow(){
for(Worker w : workers){
w.t.stop();
}
}
private class Worker implements Runnable {
private Runnable firstTask;
private Thread t;
private boolean state;//0:空闲 1:代表忙碌
public Worker(Runnable firstTask) {
super();
this.firstTask = firstTask;
this.t = new Thread(this);
}
@Override
public void run() {
runWorker(this);
}
private void runWorker(Worker w) {
Runnable task = w.firstTask;
w.firstTask = null;
while (task != null || (task = getTask()) != null) {
task.run();
task=null;
}
}
private Runnable getTask() {
boolean timeOut;
timeOut = allowCoreThreadTimeOut || workPoolSize > corePoolSize;
try {
// 如果是该线程长期存活,那么使用take线程阻塞的函数,如果是一旦没有任务就销毁线程,1.是核心线程
// 2.线程数大于核心线程,即目前任务不多,线程多余
Runnable task = timeOut ? workQueue.poll(keepAliveTime,
timeUnit) : workQueue.take();
if (task != null) {
return task;
} else {
// 如果没有任务被获取,则这个线程即将被销毁
mainLock.lock();
workPoolSize--;
mainLock.unlock();
System.out.println("当前线程被销毁");
workers.remove(this);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
}
/*
* private int ctls(int runState2, int i) { // TODO Auto-generated method
* stub return 0; }
*/
}
package com.cn.Executor;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
class MyTask implements Runnable{
private int taskNum;
public MyTask(int taskNum) {
super();
this.taskNum = taskNum;
}
@Override
public void run() {
System.out.println("正在执行:"+taskNum+"任务");
try {
Thread.sleep(1000);
System.out.println("任务"+taskNum+"結束");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
MyThreadPoolExecutor executor=new MyThreadPoolExecutor(2, 6, true, 100, TimeUnit.MILLISECONDS, new ArrayBlockingQueue
for(int i=0;i<10;i++){
Thread.sleep(100);
executor.execute(new MyTask(i));
}
}
}