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

 

posted @ 2018-07-11 09:21  Mars.wang  阅读(1259)  评论(0编辑  收藏  举报