接口:
public interface SimpleBlockingQueue<E> {
void put(E e) throws InterruptedException;
E taken() throws InterruptedException;
}
实现类:
import java.util.ArrayList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SimpleBlockingQueueImpl<E> implements SimpleBlockingQueue<E> {
private ArrayList<E> list;
private volatile int CAPACITY;
private volatile int size = 0;
private Lock lock;
private Condition notFull;//'列表不满'条件,调用put方法被阻塞的线程被注册到这个条件,也就是要满足'不满'条件,notFull.signal();唤醒需要满足'不满'条件的线程
private Condition notEmpty;//'列表不空'条件
public SimpleBlockingQueueImpl(int initialCapacity) {
CAPACITY = initialCapacity;
list = new ArrayList<>(initialCapacity);
lock=new ReentrantLock();
notFull=lock.newCondition();
notEmpty=lock.newCondition();
}
@Override
public void put(E e) throws InterruptedException {
lock.lock();
try {
while (size == CAPACITY)
notFull.await();//线程注册到'不满'条件
list.add(e);
size++;
notEmpty.signal();//插入了一个元素,唤醒取的线程
} finally {
lock.unlock();
}
}
@Override
public E taken() throws InterruptedException {
lock.lock();
try {
while (size == 0)
notEmpty.await();//线程注册到'不空'条件
E e = list.remove(0);
size--;
notFull.signal();//取出了一个元素,唤醒存的线程
return e;
} finally {
lock.unlock();
}
}
}
测试:
public class Test {
//只是作为记录的容器
static SimpleBlockingQueue<String> records=new SimpleBlockingQueueImpl<String>(150);;
public static void main(String[] args) throws InterruptedException {
SimpleBlockingQueue<Integer> sbq = new SimpleBlockingQueueImpl<Integer>(10);
// test1(sbq);
test2(sbq);
}
// 容量测试
public static void test1(SimpleBlockingQueue<Integer> sbq) throws InterruptedException {
for (int i = 0; i < 15; i++) {
sbq.put(i);
System.out.println("插入了" + (i + 1) + "个");
}
}
// 并发测试
public static void test2(SimpleBlockingQueue<Integer> sbq) throws InterruptedException {
//100个线程并发存取
MyTask[] mts=new MyTask[100];
for (int i = 0; i < 100; i++) {
mts[i]=new MyTask(sbq, i%2==0);//一半线程取,一半线程存
}
for (int i = 0; i < mts.length; i++) {
mts[i].start();
}
//睡眠5秒等待线程
Thread.sleep(5000);
System.out.println("打印完成记录:");
for (int i = 0;; i++) {
String record = records.taken();
System.out.println("第"+(i+1)+"条记录:"+record);
}
}
static class MyTask extends Thread {
SimpleBlockingQueue<Integer> sbq;
boolean isPut;
public MyTask(SimpleBlockingQueue<Integer> sbq, boolean isPut) {
this.sbq = sbq;
this.isPut = isPut;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
if (isPut) {
sbq.put(i);
} else {
sbq.taken();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
String msg=Thread.currentThread().getName()+"完成";
records.put(msg);//记录完成的线程
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}