java生產者消費者專題---談談優化(二)

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生產者消費者專題---談談優化(一)中的死鎖狀況,其實這裏也並無真正達到按需喚醒的目標,會在下一篇進行分析。

相關文章
相關標籤/搜索