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()+"运行锁");
});
}
}
}