多平台统一管理软件接口,如何实现多平台统一管理软件接口
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小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~