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