在java生產者消費者專題---談談優化(一)中說明了當知足喚醒條件時須要使用notifyAll而不是notify,可是notifyAll依然存在效率上的問題,由於notifyAll喚醒的是全部線程,因爲生產者線程會在隊列滿的時候進入等待、消費者線程會在隊列爲空的時候進入等待,所以生產者須要喚醒的條件就是隊列滿了、消費者須要喚醒的條件就是隊列空了,不能像原來同樣不加檢測條件直接喚醒,因而程序優化以下:java
package pro_con;優化
import java.util.LinkedList;this
public class QueueWithWait2<T> extends BlockingQueue<T> {
private LinkedList<T> queue = new LinkedList<>();
private final int cacheSize;.net
public QueueWithWait2(int cacheSize) {
super();
this.cacheSize = cacheSize;
}線程
public T take() {
synchronized (queue) {
while(true) {
if(queue.size()>0) {
boolean full = queue.size() == cacheSize;
T obj = queue.poll();
if(full) {
queue.notifyAll();
}
return obj;
}else {
try {
queue.wait();
} catch (InterruptedException e) {
}
}
}
}
}blog
public void put(T obj) {隊列
synchronized (queue) {
while (true) {
if (queue.size() < cacheSize) {
boolean empty=queue.size()==0;
queue.offer(obj);
if(empty) {
queue.notifyAll();
}
break;
} else {
try {
queue.wait();
} catch (InterruptedException e) {
}
}get
}
}it
}io
}
改進後平均每秒消費消息65541個比原先每秒消費個數63523稍微快點。
注意這裏的notifyAll還不能換成notify由於還會發生相似 java生產者消費者專題---談談優化(一)中的死鎖狀況,其實這裏也並無真正達到按需喚醒的目標,會在下一篇進行分析。