【操作系統】實現生產者消費者模型

最近在複習操作系統,隨手寫兩種Java實現生產者消費者模型的方式
一、信號量

import java.util.Queue;
import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;

class MessageQueue {

    private static final Semaphore FULL = new Semaphore(0);
    private static final Semaphore EMPTY = new Semaphore(10); // 初始隊列爲空
    private static final Semaphore MUTEX = new Semaphore(1);  // 互斥鎖
    private static final Random RAND_NUM_PRODUCER = new Random(System.currentTimeMillis());

    private static final Queue<Integer> QUEUE = new ConcurrentLinkedQueue<>();

    public void produce(){
        try {
            EMPTY.acquire();
            MUTEX.acquire();
            QUEUE.offer(RAND_NUM_PRODUCER.nextInt(100));
            System.out.println("【生產】生產者:" + Thread.currentThread().getName() + "   當前隊列:" + QUEUE.size());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        FULL.release();
        MUTEX.release();
    }
    public void consume(){
        try {
            FULL.acquire();
            MUTEX.acquire();
            QUEUE.poll();
            System.out.println("【消費】消費者:" + Thread.currentThread().getName() + "   當前隊列:" + QUEUE.size());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        EMPTY.release();
        MUTEX.release();
    }
}

二、Lock和Condition

import java.util.Queue;
import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class MessageQueue {

    private static final Lock LOCK = new ReentrantLock();
    private static final Condition NOT_FULL = LOCK.newCondition();
    private static final Condition NOT_EMPTY = LOCK.newCondition();

    private static final int MAX_SIZE = 10;

    private static final Random RAND_NUM_PRODUCER = new Random(System.currentTimeMillis());

    private static final Queue<Integer> QUEUE = new ConcurrentLinkedQueue<>();

    public void produce() {
        LOCK.lock();
        try{
            while(QUEUE.size() == MAX_SIZE){
                NOT_FULL.await();
            }
            QUEUE.offer(RAND_NUM_PRODUCER.nextInt(100));
            System.out.println("【生產】生產者:" + Thread.currentThread().getName() + "   當前隊列:" + QUEUE.size());
            NOT_EMPTY.signalAll();
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            LOCK.unlock();
        }
    }
    public void consume(){
        LOCK.lock();
        try{
            while(QUEUE.size() == 0){
                NOT_EMPTY.await();
            }
            QUEUE.poll();
            System.out.println("【消費】消費者:" + Thread.currentThread().getName() + "   當前隊列:" + QUEUE.size());
            NOT_FULL.signalAll();
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            LOCK.unlock();
        }
    }

}

// 以下是測試代碼
public class ProducerAndConsumer{
    public static void main(String[] args) {
        MessageQueue messageQueue = new MessageQueue();
        Thread producer = new Thread(()->{
            while(true) messageQueue.produce();
        });
        Thread consumer = new Thread(()->{
            while(true) messageQueue.consume();
        });
        producer.start();
        consumer.start();
    }
}

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