多生产者和多消费者是线程通信的经典案例,但是和生产者-消费者相比更为复杂,而且可能会产生程序假死。
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(); } }