自定义线程池
前言
- 线程池是由线程 + 队列形成的
- 创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限
- 为了避免这些问题,在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程
- 因此,我们可以根据以上要求,创建出自己的线程池

阻塞双端队列
public class MyBlockingQueue<T> {
private Deque<T> queue = new ArrayDeque<>();
private ReentrantLock lock = new ReentrantLock();
private Condition emptyWaitSet = lock.newCondition();
private Condition fullWaitSet = lock.newCondition();
private int capacity;
private final int DEFAULT_CAPACITY = 16;
public MyBlockingQueue() {
capacity = DEFAULT_CAPACITY;
}
public MyBlockingQueue(int capacity) {
this.capacity = capacity;
}
public T poll() {
lock.lock();
try {
while (queue.isEmpty()) {
emptyWaitSet.await();
}
T task = queue.removeFirst();
fullWaitSet.signal();
return task;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return null;
}
public T poll(long timeout, TimeUnit unit) {
lock.lock();
try {
long nanos = unit.toNanos(timeout);
while (queue.isEmpty()) {
if (nanos <= 0) {
return null;
}
nanos = emptyWaitSet.awaitNanos(nanos);
}
T task = queue.removeFirst();
fullWaitSet.signal();
return task;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return null;
}
public void put(T task) {
lock.lock();
try {
while (queue.size() == capacity) {
fullWaitSet.await();
}
queue.addLast(task);
emptyWaitSet.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public boolean put(T task,long timeout,TimeUnit timeUnit) {
lock.lock();
try {
long nanos = timeUnit.toNanos(timeout);
while (queue.size() == capacity) {
if (nanos <= 0) {
return false;
}
nanos = fullWaitSet.awaitNanos(nanos);
}
queue.addLast(task);
emptyWaitSet.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return true;
}
public void put(MyRejectPolicy<T> rejectPolicy, T task) {
lock.lock();
try {
if (queue.size() == capacity) {
rejectPolicy.reject(this,task);
}
queue.addLast(task);
emptyWaitSet.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public int size() {
lock.lock();
try {
return queue.size();
} finally {
lock.unlock();
}
}
}
拒绝策略
- 当线程池中的线程都处于忙碌状态,且阻塞队列已满时,我们根据需要可能会选择 阻塞等待,超时等待,抛出异常,放弃执行等方式,因此,可以利用策略模式,定义一个策略接口,由用户自己选择 需要 执行 的拒绝策略
@FunctionalInterface
interface MyRejectPolicy<T> {
void reject(MyBlockingQueue<T> queue,T task);
}
线程池
public class MyThreadPool {
private MyBlockingQueue<Runnable> taskQueue;
private Set<Worker> workers = new HashSet<>();
private int coreSize;
private long timeout;
private TimeUnit timeUnit;
private MyRejectPolicy<Runnable> rejectPolicy;
public MyThreadPool(int coreSize, long timeout, TimeUnit timeUnit,int queueCapacity,MyRejectPolicy<Runnable> rejectPolicy) {
this.taskQueue = new MyBlockingQueue<>(queueCapacity);
this.coreSize = coreSize;
this.timeout = timeout;
this.timeUnit = timeUnit;
this.rejectPolicy = rejectPolicy;
}
public MyThreadPool(int coreSize, long timeout, TimeUnit timeUnit) {
this.taskQueue = new MyBlockingQueue<>();
this.coreSize = coreSize;
this.timeout = timeout;
this.timeUnit = timeUnit;
}
public void execute(Runnable task) {
synchronized (workers) {
if (workers.size() <= coreSize) {
Worker worker = new Worker(task);
workers.add(worker);
worker.start();
} else {
taskQueue.put(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,timeUnit)) != null) {
try {
task.run();
} catch (Exception e) {
e.printStackTrace();
} finally {
task = null;
}
}
synchronized (workers) {
workers.remove(this);
}
}
}
}