101 自定义线程池实现公平锁以及淘汰策略1


package com.taotao.myktthreads.day16;

import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author wangjin
 * @title: MyBlockingQueue
 * @projectName mykt-threads
 * @description: 手写阻塞队列,任务队列
 * @date 2021/9/30 10:22
 */
public class MyBlockingQueue<T> {
    private final int capacity;
    private final LinkedList<T> queue;
    private final ReentrantLock lock = new ReentrantLock(true);
    private final Condition nullCondition = lock.newCondition();
    private final Condition fullCondition = lock.newCondition();

    public MyBlockingQueue(int capacity) {
        this.capacity = capacity;
        this.queue = new LinkedList<>();

    }

    //带超时获取
    public T poll(Long timeout, TimeUnit timeUnit) {
        lock.lock();
        try {
            long timeNano = timeUnit.toNanos(timeout);
            while (queue.isEmpty()) {
                try {
                    if (timeNano <= 0) {
                        return null;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            //获取任务
            T t = queue.removeFirst();
            fullCondition.signal();
            return t;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            lock.unlock();
        }

    }
    //阻塞增加
    public  void put(T task){
        lock.lock();
        try {
            while (queue.size()==capacity){
                try {
                    System.out.println(Thread.currentThread().getName()+"等待加入任务队列"+task);
                    fullCondition.await();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName()+"加入任务队列"+task);
            queue.addLast(task);
            nullCondition.signal();//唤醒消费者消费
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }


    public  void offer(T task,Long timeout,TimeUnit timeUnit){
        lock.lock();
        try {
            long timeNano=timeUnit.toNanos(timeout);
            try {
                while (queue.size()==capacity){
                    if(timeout <=0){
                        return;
                    }
                    timeout=fullCondition.awaitNanos(timeout);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"开始添加");
            queue.addLast(task);
            nullCondition.signal();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    public int size(){
        lock.lock();
        try {
          return queue.size();
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }finally {
            lock.unlock();
        }
    }
    //工作线程达到最大线程数后执行此方法()拒绝策略or加入任务队列
    public  void tryPut(RejectPolicy<T> rejectPolicy,T task){
        lock.lock();
        try {
            //如果任务队列也满了
            if(queue.size() ==capacity){
                //执行拒绝策略
                rejectPolicy.reject(this,task);
            }else {
                //任务队列没满
                //加入任务队列
                System.out.println(Thread.currentThread().getName()+"加入任务");
                queue.addLast(task);
                nullCondition.signal();
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}

package com.taotao.myktthreads.day16;

/**
 * @author wangjin
 * @title: MyReJectedExecutionHandler2
 * @projectName mykt-threads
 * @description:
 * @date 2021/9/30 14:27
 */
public class MyReJectedExecutionHandler2  implements RejectPolicy{
    @Override
    public void reject(MyBlockingQueue blockingQueue, Object task) {
        if(task !=null){
            blockingQueue.put(task);
        }
        System.out.println("线程池满了,拒绝线程任务");
    }
}



package com.taotao.myktthreads.day16;


import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author wangjin
 * @title: MyThreadPool
 * @projectName mykt-threads
 * @description:设计一个真正的工作线程类--work类,属于线程池内部类
 * @date 2021/9/30 11:03
 */
public class MyThreadPool {
    private final  int pollsize;
    private final MyBlockingQueue<Runnable> taskQueue;
    private final long timeout;
    private final TimeUnit timeUnit;
    private final  RejectPolicy<Runnable> rejectPolicy;
    //工作线程集合
    private final Set<Worker> workerSet;

    public MyThreadPool(int pollsize, MyBlockingQueue<Runnable> taskQueue, long timeout, TimeUnit timeUnit, RejectPolicy<Runnable> rejectPolicy) {


        this.pollsize = pollsize;
        this.taskQueue = taskQueue;
        this.timeout = timeout;
        this.timeUnit = timeUnit;
        this.rejectPolicy = rejectPolicy;
        this.workerSet = new HashSet<>();

    }

    public  void execute(Runnable task){
        synchronized (workerSet){
            if(workerSet.size()<pollsize){
                //将task包装为Worker
                Worker worker=new Worker(task) ;
                  //新创建的线程要先进入工作线程集合中
                workerSet.add(worker);
                System.out.println("");
                worker.start();

            }else {
                //工作线程数达到上限,需要加入taskQueue或者执行拒绝策略
                taskQueue.tryPut(rejectPolicy,task);
            }
        }
    }
    class Worker extends Thread{
          private Runnable task;

        public Worker(Runnable task) {
            this.task=task;
        }

        @Override
        public void run() {

            //执行任务
            //当task不为空,执行任务
             //当task执行完毕,在接着从任务队列获取任务并执行
            while(task !=null ||  (task = taskQueue.poll(timeout,timeUnit)) != null){
                       //开始执行任务
                System.out.println(this.getName()+"运行锁");
                task.run();
                //注意执行完之后要设置为null
                task=null;
            }
            synchronized (workerSet){
                System.out.println(Thread.currentThread().getName()+"释放锁");
              //  System.out.println("worker被移出"+this);
                workerSet.remove(this);
            }
        }
    }
}



package com.taotao.myktthreads.day16;

/**
 * @author wangjin
 * @title: RejectPolicy
 * @projectName mykt-threads
 * @description:
 * @date 2021/9/30 10:57
 */
public interface RejectPolicy<T> {
 void reject(MyBlockingQueue<T> blockingQueue,T task);
}

package com.taotao.myktthreads.day16;

import java.util.concurrent.TimeUnit;

/**
 * @author wangjin
 * @title: TestThreadPool
 * @projectName mykt-threads
 * @description:
 * @date 2021/9/30 14:16
 */
public class TestThreadPool {
    public static void main(String[] args) {
       MyBlockingQueue<Runnable> taskQueue = new MyBlockingQueue<>(11);
        MyThreadPool threadPool = new MyThreadPool(10, taskQueue, 0, TimeUnit.SECONDS, new MyReJectedExecutionHandler2());
        for (int i = 0; i < 10; i++) {
            int index=1;
            int finalI = i;
            threadPool.execute(()->{
               // System.out.println(Thread.currentThread().getName()+"运行锁");
            });
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章