生产者-消费者(假死)

假死

“假死”的现象就是线程进入WAITING等待状态。如果全部线程进入WAITING状态,则程序就不再执行任何业务功能了,整个项目呈现停止状态。


例子

(1)ValueObject 类

public class ValueObject {
    public static String value = "";
}

(2)P类(生产者)

  • 当生产者进行生产的时候,是实心的★,消费者消费完后,会变成空心的☆
//生产者
public class P {
    private String lock;

    public P(String lock) {
        this.lock = lock;
    }

    public void setValue() {
        synchronized (lock) {
            try {
                while (!ValueObject.value.equals("")) {
                    System.out.println(Thread.currentThread().getName() + " WAITING了");
                    lock.wait();
                }
                System.out.println(Thread.currentThread().getName() + " RUNNABLE了 ★");
                String value = System.currentTimeMillis() + "_" + System.nanoTime();
                ValueObject.value = value;
                lock.notify();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

(3)C类(消费者)

//消费者
public class C {
    private String lock;

    public C(String lock) {
        this.lock = lock;
    }

    public void getValue() {
        synchronized (lock) {
            try {
                while (ValueObject.value.equals("")) {
                    System.out.println(Thread.currentThread().getName() + " WAITING了");
                    lock.wait();
                }
                System.out.println(Thread.currentThread().getName() + " RUNNABLE了 ☆");
                ValueObject.value = "";
                lock.notify();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

(4)ThreadC(消费者线程)

public class ThreadC extends Thread {
    private C c;

    public ThreadC(C c) {
        this.c = c;
    }

    @Override
    public void run() {
        super.run();
        while (true) {
            c.getValue();
        }
    }
}

(5)ThreadP(生产者线程)

public class ThreadP extends Thread {
    private P p;

    public ThreadP(P p) {
        this.p = p;
    }

    @Override
    public void run() {
        super.run();
        while (true) {
            p.setValue();
        }
    }
}

(6)Run类

public class Run {
    public static void main(String[] args) {
        String lock = new String("");
        P p = new P(lock);
        C c = new C(lock);
        ThreadP[] pThread = new ThreadP[2];
        ThreadC[] cThread = new ThreadC[2];
        for (int i = 0; i < 2; i++) {
            pThread[i] = new ThreadP(p);
            pThread[i].setName("生产者" + (i + 1));
            cThread[i] = new ThreadC(c);
            cThread[i].setName("消费者" + (i + 1));
            pThread[i].start();
            cThread[i].start();
        }
    }
}

运行结果

  • 运行结果很长,这里截取最后出问题的一部分。

  • 可以看出,四个线程都进入了WAITING等待状态。

在这里插入图片描述


分析

原因是因为notify唤醒的不一定是异类,有可能是同类。比如生产者唤醒生产者、消费者唤醒消费者。如果按照这种情况积少成多,就会导致所有线程不能运行下去。


解决方法

将P.java和C.java文件中的notify()改成notifyAll()方法,直接同时通知同类线程和异类线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值