線程問題之線程之間的通信(二)

手寫一個單線程的生產者和消費者實現,實現生產者生產一個數字,如果已經生產線程等待,調用消費者消費這個數字,取消等待再次生產。
流程

單線程實現生產者消費者

public class OtherService {

    private int i = 1;
    // 添加一個鎖
    final private  Object  LOCK = new Object();
    private  Boolean flage = false;
	// 生產者
    public void produck(){
        synchronized (LOCK){
            if (flage){
                try {
                    LOCK.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }else{
                i++;
                System.out.println("P"+i);
                LOCK.notify();
                flage = true;
            }
        }
    }
    // 消費者
    public void Customer(){
        synchronized (LOCK){
            if(flage){
                // 消費
                System.out.println("C"+i);
                // 啓用線程
                LOCK.notify();
                flage = false;
            }else{
                try {
                    LOCK.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
}

此種方法只能實現單線程的,無法實現多線程,如果同時創建多個生產者和消費者就會出現錯誤。

public static void main(String[] args) {
        OtherService o  = new OtherService();
        Stream.of("p1","p2").forEach(
            n -> new Thread (){
                @Override
                public void run() {
                    while (true)
                        o.produck();
                }
            }.start()
        );
        Stream.of("C1","C2").forEach(c ->
            new Thread(){
                @Override
                public void run() {
                    while (true)
                        o.Customer();
                }
            }.start()
        );
    }

線程會出現假死。多線程如何解決呢。

多線程實現生產者消費者

將notify修改爲notifyAll可以解決一個生產者對應多個消費者的問題,不會有一個生產者對應多個消費者的錯誤。爲方便測試可以添加多個線程測試。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章