生產者消費者 -多線程

前提:生產者不斷地生產產品,消費者取走生產者生產的產品。生產者生產出產品後將其放到一個區域之中,消費者從這個地方去除數據java

分析: 1.是否設計多線程?是,生產者,消費者
         2.是否涉及到共享數據?有!考慮線程的安全
         3.此共享數據是誰?即爲產品的數量
         4.是否設計線程的通訊?存在生產者與消費者的通訊
public class Clerk {

    //當前商品數量
    private int product = 0;

    public synchronized void addProduct() {//同步控制併發
        while (product >= 5) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        product++;
        System.out.println(Thread.currentThread().getName() + "生成了" + product + "產品");
        notifyAll();//喚起全部阻塞的多線程
        //notify 只能通知一個在等待的對象,其餘在等待的對象不會通知,會致使多線程的併發問題

    }

    public synchronized void consumProduce() {
        while (product <= 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println(Thread.currentThread().getName() + "消費" + product + "產品");
        product--;
        notifyAll();

    }
}
public class Consumer implements Runnable {//消費者
    Clerk clerk;

    public Consumer(Clerk clerk){
        this.clerk = clerk;
    }
    @Override
    public void run() {
        System.out.println("消費者消費產品");
        while (true){
            clerk.consumProduce();
        }
    }
}
public class Product implements Runnable {//生產者
    Clerk clerk;

    public Product(Clerk clerk){
        this.clerk = clerk;
    }
    @Override
    public void run() {
        System.out.println("生產者生產產品");
        for(int i=0;i<10;i++){
            clerk.addProduct();
        }
    }
}
多線程測試類:
public class TestProductConsume {

    public static void main(String args[]){
        Clerk clerk = new Clerk();
        for(int i = 0; i < 4;i++){
            Product p1 = new Product(clerk);
            Consumer c1 = new Consumer(clerk);
            Thread t1 = new Thread(p1);
            Thread t2 = new Thread(c1);
            t1.setName("生產者"+i);
            t2.setName("消費者"+i);
            t1.start();
            t2.start();
        }
    }
}

notify只會通知一個在等待的對象,而notifyAll會通知全部在等待的對象,而且全部對象都會繼續運行安全

被wait的線程,想要繼續進行的話,必須知足2個條件:多線程

           1.通過有其餘線程notify或notifyAll,而且當前線程被通知到併發

            2.通過和其餘線程進行鎖競爭,成功獲取鎖ide

notify 僅僅通知一個線程,而且咱們不知道哪一個線程會收到通知,然而 notifyAll 會通知全部等待中的線程。換言之,若是隻有一個線程在等待一個信號燈,notify和notifyAll都會通知到這個線程。但若是多個線程在等待這個信號燈,那麼notify只會通知到其中一個,而其它線程並不會收到任何通知,而notifyAll會喚醒全部等待中的線程。測試

相關文章
相關標籤/搜索