Java多线程生产者消费者模式实现过程解析

网友投稿 232 2022-12-11


Java多线程生产者消费者模式实现过程解析

单生产者与单消费者

示例:

public class ProduceConsume {

public static void main(String[] args) {

String lock = new String("");

Produce produce = new Produce(lock);

Consume consume = new Consume(lock);

new Thread(() -> {

while (true) {

produce.setValue();

}

}, "ProductThread").start();

new Thread(() -> {

while (true) {

consume.getValue();

}

}, "ConsumeThread").start();

}

/**

* 生产者

*/

static class Produce {

private String lock;

public Produce(String lock) {

this.lock = lock;

}

public void setValue() {

try {

synchronized (lock) {

if (!ValueObject.value.equals("")) {

lock.wait();

}

String value = System.currentTimeMillis() + "_" + System.nanoTime();

System.out.println("set的值是" + value);

ValueObject.value = value;

lock.notify();

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

/**

* 消费者

*/

static class Consume {

private String lock;

public Consume(String lock) {

this.lock = lock;

}

public void getValue() {

try {

synchronized (lock) {

if (ValueObject.value.equals("")) {

lock.wait();

}

System.out.println("get的值是" + ValueObject.value);

ValueObject.value = "";

lock.notify();

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

static class ValueObject {

public static String value = "";

}

}

执行结果如下:

多生产者与多消费者

这种模式下,容易出现“假死”,也就是全部线程都进入了 WAITNG 状态,程序不在执行任何业务功能了,整个项目呈停止状态。

示例:

public class MultiProduceConsume {

public static void main(String[] args) throws InterruptedException {

String lock = new String("");

Produce produce = new Produce(lock);

Consume consume = new Consume(lock);

Thread[] pThread = new Thread[2];

Thread[] cThread = new Thread[2];

for (int i = 0; i < 2; i++) {

pThread[i] = new Thread(() ->PWotKt {

while (true) {

produce.setValue();

}

}, "生产者" + (i + 1));

cThread[i] = new Thread(() -> {

while (true) {

consume.getValue();

}

}, "消费者" + (i + 1));

pThread[i].start();

cThread[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());

}

}

static class Produce {

PWotKtprivate String lock;

public Produce(String lock) {

this.lock = lock;

}

public void setValue() {

try {

synchronized (lock) {

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();

}

}

}

static class Consume {

private String lock;

public Consume(String lock) {

this.lock = lock;

}

public void getValue() {

try {

synchronized (lock) {

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();PWotKt

}

}

}

static class ValueObject {

public static String value = "";

}

}

运行结果如图:

分析:

虽然代码中通过 wait/notify 进行通信了,但是不能保证 notify 唤醒的一定是异类,也可能是同类,比如“生产者”唤醒了“生产者”这样的情况。

解决方案:

假死出现的主要原因是有可能连续唤醒了同类。所以解决方案很简单,就是把 notify() 改为 notifyAll() 即可。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java二叉搜索树遍历操作详解【前序、中序、后序、层次、广度优先遍历】
下一篇:Java二叉搜索树基础原理与实现方法详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~