@Slf4j(topic = "c.Test")
public class Test {
public static void main(String[] args) {
ThreadPool threadPool=new ThreadPool(10,2,1000,TimeUnit.MILLISECONDS);
for (int i=0;i<5;i++){
int j=i;
threadPool.execute(()->{
log.debug("{}",j);
});
}
}
}
@FunctionalInterface
interface RejectPolicy<T> {
void reject(BlockingQueue<T> queue, T task);
}
@Slf4j(topic = "c.ThreadPool")
class ThreadPool{
private BlockingQueue<Runnable> taskQueue;
private HashSet<Worker> workers=new HashSet<>();
private int coreSize;
private long timeout;
private TimeUnit unit;
public void execute(Runnable task){
synchronized (workers){
if (workers.size()<coreSize){
Worker worker=new Worker(task);
workers.add(worker);
log.debug("新增worker对象");
worker.start();
}else {
taskQueue.put(task);
}
}
}
public ThreadPool(int queueCapcity, int coreSize, long timeout, TimeUnit unit) {
this.taskQueue = new BlockingQueue<>(queueCapcity);
this.coreSize = coreSize;
this.timeout = timeout;
this.unit = unit;
}
class Worker extends Thread{
private Runnable task;
public Worker(Runnable task) {
this.task=task;
}
@Override
public void run() {
while (task!=null||(task=taskQueue.take())!=null){
try {
task.run();
}catch (Exception e){
e.printStackTrace();
}finally {
task=null;
}
}
synchronized (workers){
log.debug("worker被移除{}",this);
workers.remove(this);
}
}
}
}
class BlockingQueue<T> {
private Deque<T> queue=new ArrayDeque<>();
private ReentrantLock lock=new ReentrantLock();
private Condition fullWaitSet=lock.newCondition();
private Condition emptyWaitSet=lock.newCondition();
private int capcity;
public BlockingQueue(int capcity) {
this.capcity = capcity;
}
public T poll(long timeout, TimeUnit unit){
lock.lock();
long nanos= unit.toNanos(timeout);
try {
while (queue.isEmpty()){
try {
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();
}
}
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();
}
}
public void put(T element){
lock.lock();
try {
while (queue.size()==capcity){
try{
fullWaitSet.await();
}catch (Exception e){
e.printStackTrace();
}
}
queue.addLast(element);
emptyWaitSet.signal();
}finally {
lock.unlock();
}
}