• 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();
        }
    }
  • 相关阅读:
    标准 IO 测试 可以打开多少流
    标准 IO fprintf 与 sprintf 函数使用
    标准 IO 测试 标准输出,输入,出错缓冲大小;全缓冲文本流大小
    标准 I/O (带缓冲)
    vim 中 ctags的应用
    链表实现队列操作
    数组实现循环队列
    数组实现顺序表
    数组结构实现顺序栈
    SDOI2019快速查询
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/9292781.html
Copyright © 2020-2023  润新知