阻塞队列
package org.butupi.pool;
import lombok.extern.slf4j.Slf4j;
import org.butupi.rejectPolicy.RejectPolicy;
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;
/**
* 任务队列
* @param
*/
@Slf4j(topic = "TaskQueue")
public class BlockingQueue {
// 1.任务队列
private Deque queue = new ArrayDeque<>();
// 2.锁,线程取任务时保护队列头和尾
private ReentrantLock lock = new ReentrantLock();
// 3.生产者条件变量
private Condition fullWaitSet = lock.newCondition();
// 4.消费者条件变量
private Condition emptyWaitSet = lock.newCondition();
// 5.容量
private int capacity;
/**
* 构造器
* @param capacity
*/
public BlockingQueue(int capacity) {
this.capacity = capacity;
}
/**
* 阻塞获取任务
* @return
*/
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();
}
}
/**
* 超时阻塞获取任务
* @return
*/
public T poll(long timeout, TimeUnit unit){
lock.lock();
try {
long nanos = unit.toNanos(timeout);// 将timeout超时时间统一转换为纳秒
// 没有任务
while (queue.isEmpty()){
try {
// 限时等待
// emptyWaitSet.await();
if (nanos <= 0){
return null;
}
nanos = emptyWaitSet.awaitNanos(nanos); // 返回的是剩余的时间
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 拿任务
T t = queue.removeFirst();
// 唤醒添加任务的线程
fullWaitSet.signal();
return t;
}finally {
lock.unlock();
}
}
/**
* 阻塞添加任务
* @param task
*/
public void put(T task){
lock.lock();
try {
// 队列满,等待
while (queue.size() == capacity){
// 阻塞等待
try {
log.info("等待加入任务队列:{}", task);
fullWaitSet.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 添加到队列尾
log.info("加入任务队列:{}", task);
queue.addLast(task);
// 唤醒拿任务的线程
emptyWaitSet.signal();
}finally {
lock.unlock();
}
}
/**
* 向阻塞队列添加任务,超时等待
* @param task
* @param timeout
* @param timeUnit
* @return
*/
public boolean offer(T task,long timeout, TimeUnit timeUnit){
lock.lock();
try {
long nanos = timeUnit.toNanos(timeout);
// 队列满,等待
while (queue.size() == capacity){
// 阻塞等待
try {
log.info("等待加入任务队列:{}", task);
if (nanos <= 0){
return false;
}
nanos = fullWaitSet.awaitNanos(nanos);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 添加到队列尾
log.info("加入任务队列:{}", task);
queue.addLast(task);
// 唤醒拿任务的线程
emptyWaitSet.signal();
return true;
}finally {
lock.unlock();
}
}
/**
* 获取任务的数量
* @return
*/
public int size(){
lock.lock();
try {
return queue.size();
}finally {
lock.unlock();
}
}
/**
* 添加任务,的方法(拒绝策略
* @param rejectPolicy
* @param task
*/
public void tryPut(RejectPolicy rejectPolicy, T task) {
lock.lock();
try {
// 判断队列是否满
if (queue.size() == capacity){
// 拒绝策略
rejectPolicy.reject(this,task);
}else {
// 队列空闲
// 添加到队列尾
log.info("加入任务队列:{}", task);
queue.addLast(task);
// 唤醒拿任务的线程
emptyWaitSet.signal();
}
}finally {
lock.unlock();
}
}
}
拒绝策略
package org.butupi.rejectPolicy;
import org.butupi.pool.BlockingQueue;
@FunctionalInterface
public interface RejectPolicy {
void reject(BlockingQueue queue,T task);
}
线程池
package org.butupi.pool;
import javafx.concurrent.Worker;
import lombok.extern.slf4j.Slf4j;
import org.butupi.rejectPolicy.RejectPolicy;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;
@Slf4j(topic = "c.ThreadPool")
public class ThreadPool {
/**
* 任务队列
*/
private BlockingQueue taskQueue;
/**
* 线程集合
*/
private HashSet workers = new HashSet();
/**
* 核心线程数
*/
private int coreSize;
/**
* 超时时间
*/
private long timeout;
/**
* 单位
*/
private TimeUnit timeUnit;
/**
* 拒绝策略
*/
private RejectPolicy rejectPolicy;
/**
* 线程池构造器
*
* @param coreSize
* @param timeout
* @param timeUnit
* @param queueCapacity
*/
public ThreadPool(int coreSize, long timeout, TimeUnit timeUnit, int queueCapacity,RejectPolicy rejectPolicy) {
this.coreSize = coreSize;
this.timeout = timeout;
this.timeUnit = timeUnit;
this.taskQueue = new BlockingQueue<>(queueCapacity);
this.rejectPolicy = rejectPolicy;
}
/**
* 执行任务
*
* @param task
*/
public void execute(Runnable task) {
synchronized (workers) {
// 当任务数没有超过核心线程数时交给worker对象执行
if (workers.size() < coreSize) {
// 创建新的线程,把它添加到线程池workers中
Worker worker = new Worker(task);
log.info("新增 worker:{},任务:{}", worker, task);
workers.add(worker);
worker.start();
} else {
// 超过coreSize时,添加到任务队列
// 1死等
// taskQueue.put(task);
// 2超时等待
// 3放弃任务
// 4主线程抛异常
// 5调用者自己执行
// 策略模式
taskQueue.tryPut(rejectPolicy,task);
}
}
}
/**
* 包装线程,有Worker包装Thread
*/
class Worker extends Thread {
private Runnable task;
public Worker(Runnable task) {
this.task = task;
}
@Override
public void run() {
// 执行任务
// 1、task不为空,直接执行
// 2、当task执行完毕,从任务队列获取任务执行
// while (task != null || (task = taskQueue.take()) != null) {
while (task != null || (task = taskQueue.poll(timeout,timeUnit)) != null) {
try {
log.info("正在执行。。。{}", task);
task.run();
} catch (Exception e) {
e.printStackTrace();
} finally {
task = null;
}
}
// 移除此线程
synchronized (workers) {
log.info("worker:{} 被移除", this);
workers.remove(this);
}
}
}
}
测试类
(含拒绝策略的lambda表达式)
package org.butupi.pool;
import com.sun.org.apache.bcel.internal.generic.ATHROW;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@Slf4j(topic = "c.TestPool")
public class Main {
public static void main(String[] args) {
ThreadPool threadPool = new ThreadPool(2, 1000, TimeUnit.MILLISECONDS, 10,
// 死等
// BlockingQueue::put
// 超时等待
// ((queue, task) -> queue.offer(task,1000,TimeUnit.MILLISECONDS))
// 放弃任务执行
// (queue,task)->log.info("放弃任务{}执行",task)
// 抛异常
// ((queue, task) -> {throw new RuntimeException("任务执行失败 "+task);})
// 调用者自己执行
(queue, task) -> task.run()
);
for (int i = 0; i < 15; i++) {
int j = i;
threadPool.execute(() -> {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("{}", j);
});
}
}
}