Java多线程之生产者/消费者模型(Synchronized版和Lock版)(附经过调试的演示代码)

所谓的生产者消费者模型,是通过一个容器来解决生产者和消费者的强耦合问题。通俗的讲,就是生产者在不断的生产,消费者也在不断的消费,可是消费者消费的产品是生产者生产的,这就必然存在一个中间容器,我们可以把这个容器想象成是一个货架,当货架空的时候,生产者要生产产品,此时消费者在等待生产者往货架上生产产品,而当货架满的时候,消费者可以从货架上拿走商品,生产者此时等待货架的空位,这样不断的循环。

具体实现代码如下,都是笔者手撸!!

class ProductAndConsumerDemo {
    
    
    public static void main(String[] args) {
    
    
        Buffer buffer = new Buffer();
        Consumer consumer = new Consumer(buffer);
        Product product = new Product(buffer);
        consumer.start();
        product.start();
    }
}

class Product extends Thread {
    
    
    private Buffer buffer;

    public Product(Buffer buffer) {
    
    
        this.buffer = buffer;
    }
    public void run() {
    
    
        for (int i = 0; i < 10; i++) {
    
    
            try {
    
    
                buffer.add(i);
                System.out.println("加入第"+i+"个线程");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}

class Consumer extends Thread {
    
    
    private Buffer buffer;

    public Consumer(Buffer buffer) {
    
    
        this.buffer = buffer;
    }

    public void run() {
    
    
        for (int i = 0; i < 10; i++) {
    
    
            int val = 0;
            try {
    
    
                val = buffer.pull();
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            System.out.println(val);
        }
    }
}

class Buffer {
    
    
    private Queue<Integer> queue = new LinkedList<>();
    private int size = 5;
    private Buffer buffer;

    public synchronized void add(int val) throws InterruptedException {
    
    
        while (queue.size() > size)//此处如果使用if,多线程环境下会造成虚假唤醒
            wait();//阻塞生产者不让其继续生产
        queue.add(val);
        notify();通知消费者消费(notify()会唤醒正在等待的线程,此处指消费者线程)

    }

    public synchronized int pull() throws InterruptedException {
    
    
       while (queue.size() == 0)
            wait();
        int val = queue.poll();
        notify();
        return val;
    }
}

代码已经经过调试,大家可随意copy到本地IDE去体验生产者/消费者的概念。

Lock版的生产者消费者模型

class BoundedBuffer {
    
    
   final Lock lock = new ReentrantLock();
   final Condition notFull  = lock.newCondition(); 
   final Condition notEmpty = lock.newCondition(); 

   final Object[] items = new Object[100];
   int putptr, takeptr, count;

   public void put(Object x) throws InterruptedException {
    
    
     lock.lock(); try {
    
    
       while (count == items.length)
         notFull.await();
       items[putptr] = x;
       if (++putptr == items.length) putptr = 0;
       ++count;
       notEmpty.signal();
     } finally {
    
     lock.unlock(); }
   }

   public Object take() throws InterruptedException {
    
    
     lock.lock(); try {
    
    
       while (count == 0)
         notEmpty.await();
       Object x = items[takeptr];
       if (++takeptr == items.length) takeptr = 0;
       --count;
       notFull.signal();
       return x;
     } finally {
    
     lock.unlock(); }
   }
 } 

不要忘记回来点赞哦!!

猜你喜欢

转载自blog.csdn.net/weixin_40485391/article/details/107794962