1. 方式一
采用synchronized
,wait/notify
的同步方式
public class BlockQueue<T>{
private int index;
private final int MAX_SIZE = 50;
private final LinkedHashMap<Integer, T> linkedHashMap = new LinkedHashMap<>();
public synchronized void put(T t) throws InterruptedException {
if (linkedHashMap.size() == MAX_SIZE) {
wait();
} else {
notifyAll();
}
linkedHashMap.put(index, t);
index++;
if (index > MAX_SIZE) index = index % MAX_SIZE;
}
public synchronized T get() throws InterruptedException {
if (linkedHashMap.size() == 0) {
wait();
} else {
notifyAll();
}
T t = null;
Iterator<Map.Entry<Integer, T>> iterator = linkedHashMap.entrySet().iterator();
if (iterator.hasNext()) {
t = linkedHashMap.remove(iterator.next().getKey());
}
return t;
}
}
2. 方式二
采用lock
、condition.await/signal
方式
public class BlockQueue2<T>{
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private int index;
private final int MAX_SIZE = 50;
private final LinkedHashMap<Integer, T> linkedHashMap = new LinkedHashMap<>();
public void put(T t) {
lock.lock();
try {
if (linkedHashMap.size() == MAX_SIZE) {
condition.await();
} else {
condition.signal();
}
linkedHashMap.put(index, t);
System.out.println("生产:" + t);
index++;
if (index == MAX_SIZE) index = index % MAX_SIZE;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public T get() {
lock.lock();
T t = null;
try {
if (linkedHashMap.size() == 0) {
condition.await();
} else {
condition.signal();
}
Iterator<Map.Entry<Integer, T>> iterator = linkedHashMap.entrySet().iterator();
if (iterator.hasNext()) {
Map.Entry<Integer, T> next = iterator.next();
t = next.getValue();
linkedHashMap.remove(next.getKey());
System.out.println("消费:" + t);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return t;
}
}
3. 方式三
使用阻塞队列BlockingDeque
public class BlockingQueue3<T> {
private BlockingDeque<T> blockingDeque = new LinkedBlockingDeque<>();
public void put(T msg) {
blockingDeque.push(msg);
}
public T get() throws InterruptedException {
return blockingDeque.take();
}
}
4. 测试程序
public static void main([String[] args) {
BlockingQueue<Integer> queue = new BlockingQueue<>();
new Thread(() -> {
for (int i = 0; i < 60; i++) {
queue.put(i);
}
}).start();
new Thread(() -> {
for (; ; ) {
queue.get();
}
}).start();
}