使用信号量实现消费者生产者模式

先贴代码:

苹果工厂:

class AppleFactory{

    private LinkedList<Integer> appleBox;

    private Integer boxSize;

    private AtomicInteger appleCurrentNum;

    // 非满锁
    private final Semaphore notFull;
    // 非空锁
    private final Semaphore notEmpty;
    // 核心锁
    private final Semaphore mutex;


    public AppleFactory(LinkedList<Integer> appleBox, Integer boxSize, AtomicInteger appleCurrentNum) {
        this.appleBox = appleBox;
        this.boxSize = boxSize;
        this.appleCurrentNum = appleCurrentNum;
        this.mutex = new Semaphore(1); // 初始化核心信号量
        this.notFull = new Semaphore(boxSize);// 初始化非满信号量
        this.notEmpty = new Semaphore(0);// 初始化非空信号量
    }

    public void putApple(){
        try {
            notFull.acquire();// 非满减1
            mutex.acquire();// 核心信号加一
            int apple = appleCurrentNum.addAndGet(1);
            appleBox.addFirst(apple);
            System.out.print("生产者,线程:" + Thread.currentThread().getName() + " ] 生产了编号为-" + apple + "-号苹果,当前苹果有:" + appleBox.size() + "个");
            System.out.println();
            mutex.release(); // 核心恢复信号量
            notEmpty.release();// 非空加一
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void takeApple(){
        try {
            notEmpty.acquire(); // 消费减的是非空信号量
            mutex.acquire();
            int apple = appleBox.removeFirst();
            System.out.print("消费者,线程:" + Thread.currentThread().getName() + " ] 消费了编号为-" + apple + "-号苹果,当前苹果有:" + appleBox.size() + "个");
            System.out.println();
            mutex.release();
            notFull.release();// 消费加的是非满信号量
        }catch (Exception e){
            e.printStackTrace();
        }
    }


}

生产者:

class Producer implements Runnable {

    private String name;

    private AppleFactory appleFactory;

    private boolean flag = true;

    Producer(String name, AppleFactory appleFactory) {
        this.name = name;
        this.appleFactory = appleFactory;
    }

    @Override
    public void run() {
        while (flag) {
            appleFactory.putApple();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void stopThread(){
        System.out.println("[ " + name +" 生产者 线程 "+ Thread.currentThread().getName() + " ] 停止了");
        this.flag = false;
    }

}

消费者:

class Consumer implements Runnable {

    private String name;

    private AppleFactory appleFactory;

    private boolean flag = true;

    Consumer(String name, AppleFactory appleFactory) {
        this.name = name;
        this.appleFactory = appleFactory;
    }

    @Override
    public void run() {
        while (flag) {
            appleFactory.takeApple();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    public void stopThread(){
        System.out.println("[ " + name +" 消费者,线程:"+ Thread.currentThread().getName() + " ] 停止了");
        this.flag = false;
    }
}

测试代码:

public class CAndPTest {

    public static void main(String[] args) {
        LinkedList<Integer> appleBox = new LinkedList<>();
        Integer boxSize = 5;
        AtomicInteger initNum = new AtomicInteger(0);
        AppleFactory appleFactory = new AppleFactory(appleBox,boxSize,initNum);
        ExecutorService executorService = Executors.newFixedThreadPool(6);
        List<Producer> producers = new ArrayList<>();
        List<Consumer> consumers = new ArrayList<>();
        for (int i = 0 ; i  < 3 ; i++){
            Producer producer = new Producer("P_" + (i + 1),appleFactory);
            producers.add(producer);
            Consumer consumer = new Consumer("C_" + (i + 1),appleFactory);
            consumers.add(consumer);
            executorService.submit(producer);
            executorService.submit(consumer);
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0 ; i  < 3 ; i++){
            producers.get(i).stopThread();
            consumers.get(i).stopThread();
        }
        executorService.shutdown();
    }
}

信号量原理:

信号量创建的时候会有一个初始的值,假设为1。每一个acquire的时候就减1,release就加一,如果acquire的时候减一如果是小于等于零的话,就等待,如果是大于零的话就等待。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值