使用ReetrantLock和Candition實現生產者消費者模型

package com.zjw;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 生產者消費者問題
 */
public class ReetrantLockTest {

  static class MyContainer<T> {

    private List<T> container = new LinkedList<>();
    private Integer maxSize;
    private Integer size = 0;

    private Lock lock = new ReentrantLock();
    private Condition producer = lock.newCondition();
    private Condition consumer = lock.newCondition();

    MyContainer(Integer maxSize) {
      this.maxSize = maxSize;
    }

    void put(T t) throws InterruptedException {
      lock.lock();
      // 當容器裝滿時讓生產者等待,使用while循環檢測
      while (this.size == this.maxSize) {
        System.out.println("+++生產者等待...");
        producer.await(); // 會將鎖釋放出來,在被喚醒時需要重新獲取鎖
      }
      container.add(t);
      size++;
      System.out.println("+生產: " + t + ", current size: " + size);
      consumer.signalAll();
      lock.unlock();
    }

    T get() throws InterruptedException {
      lock.lock();
      // 當容器爲空時讓消費者等待,使用while循環檢測
      while (this.size == 0) {
        System.out.println("---消費者等待...");
        consumer.await(); // 會將鎖釋放出來,在被喚醒時需要重新獲取鎖
      }
      T result = container.remove(0);
      size--;
      producer.signalAll();
      System.out.println("-消費: " + result + ", current size: " + size);
      lock.unlock();
      return result;
    }
  }

  public static void main(String[] args) throws InterruptedException {
    MyContainer<Integer> container = new MyContainer<>(5);
    Random random = new Random();
    // 消費者 5個
    for (int i = 0; i < 5; i++) {
      new Thread(() -> {
        while (true) {
          try {
            TimeUnit.MILLISECONDS.sleep(random.nextInt(5000));
            container.get();
          } catch (InterruptedException e) {
            System.out.println("An error: " + e);
            e.printStackTrace();
          }
        }
      }).start();
    }
    TimeUnit.SECONDS.sleep(5);
    // 生產者 5個
    for (int i = 0; i < 5; i++) {
      new Thread(() -> {
        while (true) {
          try {
            TimeUnit.MILLISECONDS.sleep(random.nextInt(5000));
            container.put(random.nextInt(10000));
          } catch (InterruptedException e) {
            System.out.println("An error: " + e);
            e.printStackTrace();
          }
        }
      }).start();
    }
  }
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章