一、BlockingQueue代码
- 使用ReentrantLock实现上锁;
- 使用Condition实现阻塞式添加与弹出元素;
public class MyBlockingQueue<T> {
private int capacity;
private ArrayDeque<T> queue;
private ReentrantLock lock;
private Condition full;
private Condition empty;
public MyBlockingQueue(int capacity, boolean fair) {
this.capacity = capacity;
queue = new ArrayDeque<>();
lock = new ReentrantLock();
full = lock.newCondition();
empty = lock.newCondition();
}
/**
* 阻塞放入
*/
public void put(T t) {
if (t == null) {
throw new NullPointerException();
}
lock.lock();
try {
while (queue.size() == capacity) {
full.await();
}
queue.add(t);
empty.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
/**
* 阻塞式获取
*/
public T poll() {
T t = null;
lock.lock();
try {
while (queue.size() == 0){
empty.await();
}
t = queue.poll();
full.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
return t;
}
}
}
二、TheadPool
- worker内部类,实现Runable接口,使用while循环实现线程复用;
- 提供execute方法:
1.当线程池中线程数小于coreSize,创建新worker进程执行任务;
2.当线程池中线程数不小于coreSize,将任务放入阻塞队列等待空闲线程; - 提供shutdown方法,销毁线程池;
public class MyThreadPool {
private int coreSize;
private volatile boolean running;
private Set<MyWorker> workers;
private MyBlockingQueue<Runnable> queue;
public MyThreadPool(int coreSize, MyBlockingQueue<Runnable> queue){
this.coreSize = coreSize;
this.running = true;
this.workers = new HashSet<>();
this.queue = queue;
}
public void execute(Runnable task){
if (task == null){
throw new NullPointerException();
}
if (workers.size() < coreSize){
MyWorker myWorker = new MyWorker(task);
workers.add(myWorker);
myWorker.thread.start();
}else {
queue.put(task);
}
}
public void shutdown(){
this.running = false;
}
class MyWorker implements Runnable{
private Runnable task;
private Thread thread;
public MyWorker(Runnable task){
this.task = task;
this.thread = new Thread(this);// !!!
}
@Override
public void run(){
while (running && (task != null || (task = queue.poll()) != null)){
task.run();
task = null;// !!!
}
}
}
}
三、测试
public class Test {
public static void main(String[] args) {
MyBlockingQueue<Runnable> queue = new MyBlockingQueue<>(5, false);
MyThreadPool pool = new MyThreadPool(2, queue);
for (int i =0; i < 20; i++){
final int j = i;
pool.execute(() -> System.out.println(j + "____" + Thread.currentThread().getName()));
}
// pool.shutdown();
}
}
运行结果:
0____Thread-0
1____Thread-1
2____Thread-0
3____Thread-1
4____Thread-0
5____Thread-1
6____Thread-0
7____Thread-1
9____Thread-1
8____Thread-0
10____Thread-1
12____Thread-1
11____Thread-0
13____Thread-1
14____Thread-0
15____Thread-1
16____Thread-0
17____Thread-1
18____Thread-0
19____Thread-1