Java多线程生产者消费者模式实现过程解析
时间:2021-06-26 08:45:01|栏目: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(() -> {
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 {
private 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();
}
}
}
static class ValueObject {
public static String value = "";
}
}
运行结果如图:

分析:
虽然代码中通过 wait/notify 进行通信了,但是不能保证 notify 唤醒的一定是异类,也可能是同类,比如“生产者”唤醒了“生产者”这样的情况。
解决方案:
假死出现的主要原因是有可能连续唤醒了同类。所以解决方案很简单,就是把 notify() 改为 notifyAll() 即可。
上一篇:彻底搞明白Spring中的自动装配和Autowired注解的使用
栏 目:JAVA代码
下一篇:解决IntelliJ IDEA创建spring boot无法连接http://start.spring.io/问题
本文地址:http://www.codeinn.net/misctech/148079.html


阅读排行
- 1Java Swing组件BoxLayout布局用法示例
- 2java中-jar 与nohup的对比
- 3Java邮件发送程序(可以同时发给多个地址、可以带附件)
- 4Caused by: java.lang.ClassNotFoundException: org.objectweb.asm.Type异常
- 5Java中自定义异常详解及实例代码
- 6深入理解Java中的克隆
- 7java读取excel文件的两种方法
- 8解析SpringSecurity+JWT认证流程实现
- 9spring boot里增加表单验证hibernate-validator并在freemarker模板里显示错误信息(推荐)
- 10深入解析java虚拟机




