自定义线程池的创建
1先创建一个阻塞队列,用于存放多余的任务
package myselfPool;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j
class blockingQueue<T> {
//任务队列
private Deque<T> queue = new ArrayDeque<>();
//锁
private ReentrantLock lock = new ReentrantLock();
//生产者条件变量
private Condition fullWaitSet = lock.newCondition();
//消费者条件变量
private Condition emptyWaitSet = lock.newCondition();
//任务队列的数量
private int capcity;
public blockingQueue(int capcity) {
this.capcity = capcity;
}
//阻塞获取
public T take()//从头部获取队列
{
lock.lock();//用锁保护任务
try {
while (queue.isEmpty())//队列空了,消费者要等待新的任务进来
{
try {
emptyWaitSet.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
T t= queue.removeFirst();
fullWaitSet.signal();//生产者队列被唤醒
return t;
}finally {
lock.unlock();
}
}
//带超时的阻塞获取
public T poll(long timeout, TimeUnit unit)
{
lock.lock();//用锁保护任务
long nanos = unit.toNanos(timeout);//将timeout统一转化为纳秒
try {
while (queue.isEmpty())//队列空了,消费者要等待新的任务进来
{
try {
if(nanos <= 0)
return null;
nanos = emptyWaitSet.awaitNanos(nanos);//返回的是剩余时间
} catch (InterruptedException e) {
e.printStackTrace();
}
}
T t= queue.removeFirst();
System.out.println("从等待队列中删除..");
fullWaitSet.signal();
return t;
}finally {
lock.unlock();
}
}
//阻塞添加
public void put(T element)//从尾部添加队列
{
lock.lock();
try {
while (queue.size() == capcity)//队列满了,生产者要等待任务消费了来
{
try {
fullWaitSet.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
queue.addLast(element);
emptyWaitSet.signal();//消费者队列
}finally {
lock.unlock();
}
}
//获取大小
public int size()
{
lock.lock();
int sizes;
try {
sizes = queue.size();
}finally {
lock.unlock();
}
return sizes;
}
public void tryPut(RejectPolicy<T> rejectPolicy, T task)
{
lock.lock();
try {
//判断队列是不是满了
if(queue.size() == capcity)
{
rejectPolicy.reject(this, (Runnable) task);
}else
{
log.debug("把任务加入阻塞队列*******{}",task);
queue.addLast(task);//把任务入阻塞队列
emptyWaitSet.signal();//唤醒消费者
}
}finally {
lock.unlock();
}
}
}
然后创建一个自己定义的线程池
package myselfPool;
import lombok.extern.slf4j.Slf4j;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;
@Slf4j(topic ="c.ThreadPool")
class ThreadPool {
private blockingQueue<Runnable> taskQueue;//任务队列
private HashSet<Worker> workers = new HashSet<Worker>();//线程集合
private int coreSize;//核心线程数
private long timeOut;//获取任务的超时时间
private TimeUnit timeUnit;//时间单位
private RejectPolicy<Runnable> rejectPlicy;//拒绝策略
public ThreadPool(int queueCapcity, int coreSize, long timeOut, TimeUnit timeUnit, RejectPolicy<Runnable> rejectPlicy) {
this.taskQueue = new blockingQueue<>(queueCapcity);
this.coreSize = coreSize;
this.timeOut = timeOut;
this.timeUnit = timeUnit;
this.rejectPlicy = rejectPlicy;
}
public void excute(Runnable task)//执行任务
{
synchronized (workers)
{
if(workers.size() < coreSize)//阻塞队列里面的线程数小于核心线程数,那么创建workers.size()这么多的线程
{
Worker worker = new Worker(task);//初始化worker线程
log.debug("新增加worker...{}",task);
log.debug("workers.size()....{}",workers.size());
workers.add(worker);//把woker线程加入到wokers线程集合里面
worker.start();//woker线程启动
}else
{
log.debug("加入任务队列....{}",task);
//taskQueue.put(task);//因为任务数超过了核心线程数coreSize,所以把task加入到阻塞队列进行缓存
//死等
taskQueue.tryPut(rejectPlicy,task);
//带超时等待
}
}
}
class Worker extends Thread
{
private Runnable task;
public Worker(Runnable task) {
this.task = task;
}
@Override
public void run() {
//当task不为null时,直接执行任务
//当task执行完毕之后,阻塞队列里面还有任务时,从里面获取任务,在执行
while (task != null || (task = taskQueue.take() )!= null)//task = taskQueue.poll(1000,TimeUnit.MILLISECONDS
{
try {
log.debug("正在执行task对象...{}",task);
task.run();
}finally {
task = null;
}
}
synchronized (workers)
{
log.debug("正在删除task对象...{}",task);
workers.remove(task);
}
}
}
}
定义一个拒绝策略的接口
package myselfPool;
interface RejectPolicy<T> {//定义成为泛型,可以接受更多的参数类型
public void reject(blockingQueue<T> queue,Runnable task);//拒绝策略
}
测试这个自定义线程池
package myselfPool;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@Slf4j(topic ="c.ThreadPool")
public class showPool {
public static void main(String[] args) throws InterruptedException {
ThreadPool pools = new ThreadPool(10,3,1000, TimeUnit.MILLISECONDS,(queue, task)->
{
queue.put(task);//死等,之前的拒绝策略没有改变
//还可以有更多的拒绝策略,比如结束任务,抛出异常等等
});
for(int i = 0; i < 5; i++)
{
int j = i;
pools.excute(
()->{log.debug("....now...{}...",j);}
);
}
}
}
截图展示:
类