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 @   Mars.wang  阅读(1263)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示