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()+"運行鎖");
            });
        }
    }
}

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