3.1.11生产者消费者模式(假死)

来源:互联网 发布:淘宝服装店策划书 编辑:程序博客网 时间:2024/05/22 02:03

package demo;/** * Created by sunyifeng on 17/10/16. */public class MessageObject {    public static String value = "";}
package demo;import com.sun.beans.decoder.ValueObject;/** * Created by sunyifeng on 17/10/16. */public class P {    private String lock;    public P(String lock) {        super();        this.lock = lock;    }    public void setValue(){        try {            synchronized (lock) {                while (!MessageObject.value.equals("")) {                    System.out.println("生产者开始等待,线程名称:" + Thread.currentThread().getName());                    lock.wait();                }                System.out.println("生产者结束等待,线程名称:" + Thread.currentThread().getName());                String value = System.currentTimeMillis() + "_" + System.nanoTime();                MessageObject.value = value;                lock.notify();            }        } catch (InterruptedException e) {            e.printStackTrace();        }    }}
package demo;/** * Created by sunyifeng on 17/10/16. */public class C {    private String lock;    public C(String lock) {        super();        this.lock = lock;    }    public void getValue(){        try {            synchronized (lock) {                while (MessageObject.value.equals("")) {                    System.out.println("消费者开始等待,线程名称:" + Thread.currentThread().getName());                    lock.wait();                }                System.out.println("消费者结束等待,线程名称:" + Thread.currentThread().getName());                MessageObject.value = "";                lock.notify();            }        } catch (InterruptedException e) {            e.printStackTrace();        }    }}
package demo;/** * Created by sunyifeng on 17/10/16. */public class ThreadP extends Thread {    private P p;    public ThreadP(P p) {        super();        this.p = p;    }    @Override    public void run(){        while (true) {            p.setValue();        }    }}
package demo;/** * Created by sunyifeng on 17/10/16. */public class ThreadC extends Thread {    private C c;    public ThreadC(C c) {        super();        this.c = c;    }    @Override    public void run(){        while (true) {            c.getValue();        }    }}
package demo;/** * Created by sunyifeng on 17/10/16. */public class Run {    public static void main(String[] args) throws InterruptedException {        String lock = new String("");        //        P p = new P(lock);        C c = new C(lock);        //        ThreadP[] threadPs = new ThreadP[2];        ThreadC[] threadCs = new ThreadC[2];        //        for (int i = 0; i < 2; i++) {            threadPs[i] = new ThreadP(p);            threadPs[i].setName("生产者" + (i + 1));            threadCs[i] = new ThreadC(c);            threadCs[i].setName("消费者" + (i + 1));            threadPs[i].start();            threadCs[i].start();        }        //        Thread.sleep(5000);        Thread[] threadArray = new Thread[Thread.currentThread().getThreadGroup().activeCount()];        Thread.currentThread().getThreadGroup().enumerate(threadArray);        //        for (int i = 0; i < threadArray.length; i++) {            System.out.println(threadArray[i].getName() + "," + threadArray[i].getState());        }    }}
运行结果:

。。。。。。

消费者开始等待,线程名称:消费者2
生产者结束等待,线程名称:生产者1
生产者开始等待,线程名称:生产者1
消费者结束等待,线程名称:消费者1
消费者开始等待,线程名称:消费者1
消费者开始等待,线程名称:消费者2
生产者结束等待,线程名称:生产者2
生产者开始等待,线程名称:生产者2
生产者开始等待,线程名称:生产者1
main,RUNNABLE
Monitor Ctrl-Break,RUNNABLE
生产者1,WAITING
消费者1,WAITING
生产者2,WAITING
消费者2,WAITING

程序分析:

所有的线程都是witing状态,在代码中有wait/notify的通讯,但是唤醒的是同类,造成所有的线程都是等待状态,程序就出现“假死状态”。

解决办法:

将所有的notify改成notifyAll。