自定义线程池

自定义线程池的创建
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);}
            );
          
        }
    }
}

截图展示:
在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值