java生產者消費者專題---談談wait與sleep

生產者消費者是個經典的話題了,此次主要經過這個話題談談wait方法與sleep方法。java

wait方法和sleep方法都是讓出cpu佔有權,讓其它線程可以獲得運行,不一樣的地方在於wait方法能夠經過notify或者notifyAll方法主動喚醒或者wait必定的等待時間自動恢復運行,而sleep方法只能在等待必定的時間後自動恢復運行。測試

通常咱們看到的生產者消費者實現都是經過wait、notify、notifyAll或者是condition接口的await、signal、signalAll方法實現的。此次咱們想看看經過sleep方法實現與wait方法實現的效率有多大差異。this

wait方式實現:線程

package pro_con;blog

import java.util.LinkedList;接口

public class QueueWithWait<T> extends BlockingQueue<T> {
    private LinkedList<T> queue = new LinkedList<>();
    private final int cacheSize;隊列

    public QueueWithWait(int cacheSize) {
        super();
        this.cacheSize = cacheSize;
    }ci

    public T take() {
        synchronized (queue) {
            while(true) {
                if(queue.size()>0) {
                    T obj = queue.poll();
                    queue.notify();
                    return obj;
                }else {
                    try {
                        queue.wait();
                    } catch (InterruptedException e) {
                    }
                }
            }
        }
    }it

    public void put(T obj) {io

        synchronized (queue) {
            while (true) {
                if (queue.size() < cacheSize) {
                    queue.offer(obj);
                    queue.notify();
                    break;
                } else {
                    try {
                        queue.wait();
                    } catch (InterruptedException e) {
                    }
                }

            }
        }

    }

}
 

 

sleep方式實現:

package pro_con;

import java.util.LinkedList;

public class QueueWithSleep<T> extends BlockingQueue<T> {

    private LinkedList<T> queue = new LinkedList<>();
    private final int cacheSize;

    public QueueWithSleep(int cacheSize) {
        super();
        this.cacheSize = cacheSize;
    }

    public T take() {
        while (true) {
            synchronized (queue) {
                if (queue.size() > 0) {
                    T obj = queue.poll();
                    return obj;
                } else {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                    }
                }
            }
        }
    }

    public void put(T obj) {
        while (true) {
            synchronized (queue) {
                if (queue.size() < cacheSize) {
                    queue.offer(obj);
                    break;
                } else {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                    }
                }

            }
        }

    }

}

測試結果:

wait方式的前7次結果以下圖所示

sleep方式的前7次結果以下圖所示

結果是很明顯的,wait方式比sleep方式效率要高出不少,可能會簡單的認爲sleep的時間過長致使的,那麼把sleep方法去掉後結果以下:

結果發現效率與wait方式差很少,可是仔細觀察會發現這種去掉sleep的方法結果是不穩定的,不像wait方法穩定在290萬左右,緣由是

去掉sleep方法後同一個put或者take方法在達到臨界條件時有必定概率會屢次循環,不像wait方法主動讓出cpu佔用權,從而下降了程序

的效率。

結論:

主流的生產者消費者模式仍是用wait或者condition接口的await方式,但還有一種無鎖隊列會比這更加高效。

 

代碼下載連接:https://pan.baidu.com/s/1ciLBNiIc9670cwdat2qspQ 密碼:z5d1

相關文章
相關標籤/搜索