java 線程間通信,多生產者多消費者問題

java 線程間通信,多生產者多消費者問題

/**
 * 多生產者,多消費者的問題
 * if判斷標記,只判斷一次,會導致不該 運行的線程運行了,出現 了數據錯誤 的情況
 * while判斷標記,解決了線程獲取執行權後,是否要運行
 *
 *
 * notify:只能喚醒一個線程,如果 本方喚醒 了本方,沒有意義 ,而且 while 判斷標記 + notify會導致死鎖
 * notifyAll:解決了本方線程一定會喚醒對方線程的問題
 *
 * jdk1.5以後將同步 和鎖封裝成了對象 ,並將操作鎖的隱式方式 定義 到了該 對象 中,
 * 將隱式動作變成 了顯示 動作
 *
 *
 *
 * Lock接口:出現替代了同步代碼塊或者同步函數,將同步的隱式鎖操作變成 現實鎖操作
 * 同時更爲靈活,可以一個鎖上加上多組監視器
 * lock():獲取鎖
 * unlock():釋放鎖,通常需要定義finally代碼塊中
 *
 * Condition接口:出現 替代 了Object中的wait notify notifyAll方法
 *                將這些監視器方法單獨進行了封裝,變成 Condition監視器對象
 *                可以任意鎖進行組合
 * await();signal();signlAll()
 */
class Resource{
    private String name;
    private int count = 1;
    private boolean flag;

    //創建一個鎖對象
    Lock lock = new ReentrantLock();
    //通過已有的鎖獲取該鎖上的監視器對象
    Condition condition = lock.newCondition();

    //通過 已有的鎖獲取兩組監視器,一級監視生產者,一組監視消費者
    Condition pro_con = lock.newCondition();
    Condition consumer_con = lock.newCondition();


    public  void set3(String name){
        lock.lock();
        try {

            while (flag){
                try {
//                    this.wait();
//                    condition.await();
                    pro_con.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.name = name+count;
            count++;
            System.out.println(Thread.currentThread().getName()+"..生產者..."+this.name);
            flag = true;
//            notifyAll();
//            condition.signalAll();
            consumer_con.signal();
        }finally {
            lock.unlock();
        }

    }

    public synchronized void out3(){
        lock.lock();
        try {
            while (!flag){
                try {
//                    this.wait();
//                    condition.await();
                    consumer_con.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName()+".......消費者........"+this.name);
            flag = false;
//            notifyAll();
//            condition.signalAll();
            pro_con.signal();
        }finally {
            lock.unlock();
        }

    }

    public  void set2(String name){
        lock.lock();
        try {
//            if (flag)  這裏以前用的是if,會發生安全問題
            while (flag){
                try {
//                    this.wait();  第一次的用法
                    condition.await();
//                    pro_con.await();第三次的用法
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.name = name+count;
            count++;
            System.out.println(Thread.currentThread().getName()+"..生產者..."+this.name);
            flag = true;
//            notifyAll();第一次的用法
//            condition.signalAll();第三次的用法
            consumer_con.signal();
        }finally {
            lock.unlock();
        }

    }

    public synchronized void out2(){
        lock.lock();
        try {
            while (!flag){
                try {
//                    this.wait();第一次的用法
                    condition.await();
//                    consumer_con.await();第三次的用法
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName()+".......消費者........"+this.name);
            flag = false;
//            notifyAll();
//            condition.signalAll();
            pro_con.signal();
        }finally {
            lock.unlock();
        }

    }
    public synchronized void set(String name){
        // if (flag)  這裏以前用的是if,會發生安全問題
        while (flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.name = name+count;
        count++;
        System.out.println(Thread.currentThread().getName()+"..生產者..."+this.name);
        flag = true;
        notifyAll();
    }
    public synchronized void out(){
        while (!flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName()+".......消費者........"+this.name);
        flag = false;
        notifyAll();
    }
}

class prodeucer implements Runnable{

    private Resource resource;

    public prodeucer(Resource resource) {
        this.resource = resource;
    }

    @Override
    public void run() {
        while (true){
            resource.set("烤鴨");
        }
    }
}
class consumer implements Runnable{

    private Resource resource;

    public consumer(Resource resource) {
        this.resource = resource;
    }

    @Override
    public void run() {
        while (true) {
            resource.out();
        }
    }
}

public class ProducerConsumerDemo {
    public static void main(String[] args){
        Resource resource = new Resource();
        prodeucer prodeucer = new prodeucer(resource);
        consumer consumer = new consumer(resource);
        Thread t0 = new Thread(prodeucer);
        Thread t1 = new Thread(prodeucer);
        Thread t2 = new Thread(consumer);
        Thread t3 = new Thread(consumer);
        t0.start();
        t1.start();
        t2.start();
        t3.start();
    }
}

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