java多线程之多生产者-多消费者

时间:2023-03-09 06:41:44
java多线程之多生产者-多消费者

多生产者和多消费者是线程通信的经典案例,但是和生产者-消费者相比更为复杂,而且可能会产生程序假死。

public class Product {
private MyStack myStack; public Product(MyStack myStack) {
this.myStack = myStack;
} public void pushService(){
myStack.push();
}
} public class Consumer {
private MyStack myStack; public Consumer(MyStack myStack) {
this.myStack = myStack;
} public void popService(){
myStack.pop();
}
} public class ThreadP extends Thread {
private Product product; public ThreadP(Product product) {
this.product = product;
} @Override
public void run() {
while (true) {
product.pushService();
}
}
} public class ThreadC extends Thread{
private Consumer consumer; public ThreadC(Consumer consumer) {
this.consumer = consumer;
} @Override
public void run() {
while (true) {
consumer.popService();
}
}
} public class MyStack {
private List list = new ArrayList<>(); synchronized public void push() {
try {
while (list.size() == 1) {
this.wait();
}
list.add("anything=" + Math.random());
this.notifyAll();
System.out.println("push=" + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
} synchronized public String pop() {
String returnValue = "";
try {
while (list.size() == 0) {
System.out.println("pop wait begin"+Thread.currentThread().getName());
this.wait();
}
returnValue = "" + list.size();
list.remove(0);
Thread.sleep(1000);
this.notifyAll();
System.out.println("pop end"+list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
return returnValue;
}
} /**
* Created by wangbin10 on 2018/7/10.
* 多生产多消费的情况程序运行后出现假死:
* 原因是虽然代码中已经wait/notify进行通信了,但是不能保证notify唤醒的就是是同类还是异类
* 可能会出现生产者唤醒生产者,消费者唤醒消费者的情况,长此以往,所有线程都进行等待
* 解决的办法就是将notify换成notifyAll
*/
public class Test {
public static void main(String[] args) {
MyStack myStack=new MyStack();
Product p1 = new Product(myStack);
Product p2 = new Product(myStack);
Product p3 = new Product(myStack);
Product p4 = new Product(myStack); ThreadP tp1=new ThreadP(p1);
ThreadP tp2=new ThreadP(p2);
ThreadP tp3=new ThreadP(p3);
ThreadP tp4=new ThreadP(p4); tp1.start();
tp2.start();
tp3.start();
tp4.start(); Consumer c1 = new Consumer(myStack);
Consumer c2 = new Consumer(myStack);
Consumer c3 = new Consumer(myStack);
Consumer c4 = new Consumer(myStack); ThreadC tc1 = new ThreadC(c1);
ThreadC tc2 = new ThreadC(c2);
ThreadC tc3 = new ThreadC(c3);
ThreadC tc4 = new ThreadC(c4); tc1.start();
tc2.start();
tc3.start();
tc4.start();
}
}