- 自定义阻塞队列
- 自定义工作线程
- 自定义拒绝策略
·
package threadBase.threadPool;
import com.sun.corba.se.impl.oa.toa.TOA;
import lombok.extern.slf4j.Slf4j;
import threadBase.model.TimeProxy;
import java.io.File;
import java.io.FileDescriptor;
import java.sql.Connection;
import java.sql.Time;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.BiConsumer;
@FunctionalInterface
interface RejectPolicy<T> {
public void reject(MyBlockingQueue<T> que, T task) ;
}
@Slf4j(topic = "c.ThreadPool")
class ThreadPool <T>{
private MyBlockingQueue<Runnable> taskQueue;
private HashSet<Worker> workers = new HashSet<>();
private int coresize;
private long timeout;
private TimeUnit unit;
private RejectPolicy<Runnable> rejectPolicy;
public ThreadPool(int coresize, long timeout, TimeUnit unit, int queCapcity, RejectPolicy<Runnable>reject) {
this.coresize = coresize;
this.timeout = timeout;
this.unit = unit;
this.taskQueue = new MyBlockingQueue<>(queCapcity);
this.rejectPolicy = reject;
}
public void execute(Runnable task) {
synchronized (workers) {
if (workers.size() < coresize) {
Worker worker = new Worker(task);
log.debug("新增 worker{}, {}", worker, task);
workers.add(worker);
worker.start();
} else {
taskQueue.tryPut(rejectPolicy, task);
}
}
}
class Worker extends Thread{
private Runnable task;
public Worker (Runnable task) {
this.task = task;
}
@Override
public void run() {
while(task != null || ((task = taskQueue.poll(timeout, unit)) != null)) {
try {
log.debug("正在执行任务...{}", task);
task.run();
} catch (Exception e) {
e.printStackTrace();
}
finally {
task = null;
}
}
synchronized (workers) {
log.debug("{} 被移除", this);
workers.remove(this);
}
}
}
}
@Slf4j(topic = "c.BlockQueue")
class MyBlockingQueue <T>{
private Deque<T> queue = new ArrayDeque<>();
private ReentrantLock lock = new ReentrantLock();
private Condition full = lock.newCondition();
private Condition empty = lock.newCondition();
private int capcity;
public MyBlockingQueue(int capcity) {
this.capcity = capcity;
}
public T take() {
lock.lock();
try {
while (queue.isEmpty()) {
try {
empty.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
T ret = queue.removeFirst();
full.signalAll();
return ret;
}
finally {
lock.unlock();
}
}
public void put(T element) {
lock.lock();
try {
while (queue.size() >= capcity) {
log.debug("等待加入任务队列 {} ...", element);
full.await();
}
log.debug("加入任务队列 {}", element);
queue.addLast(element);
empty.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public int size() {
return this.capcity;
}
public T poll(long timeout, TimeUnit unit) {
lock.lock();
try {
long nanos = unit.toNanos(timeout);
while(queue.isEmpty()) {
try {
if (nanos <= 0) return null;
nanos = empty.awaitNanos(nanos);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
T t = queue.removeFirst();
full.signalAll();
return t;
} finally {
lock.unlock();
}
}
public boolean offer(T task, long timeout, TimeUnit unit) {
lock.lock();
try {
long nanos = unit.toNanos(timeout);
while (queue.size() >= capcity) {
log.debug("等待加入任务队列 {} ... {}", task, nanos);
if (nanos <= 0)
return false;
try {
nanos = full.awaitNanos(nanos);
} catch (Exception e) {
e.printStackTrace();
}
}
log.debug("加入任务队列 {}", task);
queue.addLast(task);
empty.signalAll();
return true;
} finally {
lock.unlock();
}
}
public void tryPut(RejectPolicy<T>rejectPolicy, T task) {
lock.lock();
try {
if (queue.size() == capcity) {
rejectPolicy.reject(this, task);
} else {
log.debug("加入任务队列 {}", task);
queue.addLast(task);
empty.signalAll();
}
}
finally {
lock.unlock();
}
}
}
@Slf4j(topic = "c.TestPool")
public class ThreadPoolTest<T> {
public static void main(String[] args) {
ThreadPool<Runnable> threadPool = new ThreadPool<Runnable>(2, 1000, TimeUnit.MILLISECONDS, 10, (queue, task)->{
task.run();
});
for (int i = 0; i < 15; i++) {
int j = i;
threadPool.execute(()->{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("{}", j);
});
}
}
}