Semaphore实现生产者与消费者问题

Semaphore实现生产者与消费者问题,通俗易懂

一、分析

生产者与消费者中需要关注的核心问题有两个:

  1. 生产者不能同时放
  2. 消费者不能同时消费

对象抽象

消费者、生产者、仓库

二、源码:

仓库

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;

/**
 * @author VernHe
 */
public class Buffer {
    //同时进入核心区的人数
    Semaphore mutex = new Semaphore(1);

    //空位的数量
    Semaphore notFull = new Semaphore(5);

    //产品的数量
    Semaphore notEmpty = new Semaphore(0);

    //操作的仓库
    private List<String> list = new ArrayList<>(5);

    /**
     * 放入产品
     * @param str
     * @throws InterruptedException
     */
    public void write(String str) throws InterruptedException {
        //仓库有空位时
        notFull.acquire();
        try {
            //看有没有线程在核心区
            mutex.acquire();
            //放入产品
            list.add(str);
        } finally {
            //退出核心区
            mutex.release();
            //增加一个不空的位置
            notEmpty.release();
        }
    }

    /**
     * 取出产品
     * @return
     * @throws InterruptedException
     */
    public String read() throws InterruptedException{
        //有产品可以拿的时候
        notEmpty.acquire();
        try {
            //进入核心区
            mutex.acquire();
            //拿产品
            return list.remove(0);
        } finally {
            //退出核心区
            mutex.release();
            //空位增加
            notFull.release();
        }

    }
}

生产者

/**
 * 生产者,放入产品
 * @author VernHe
 */

public class Producer implements Runnable{
    private Buffer buffer;

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

    public Buffer getBuffer() {
        return buffer;
    }

    public void setBuffer(Buffer buffer) {
        this.buffer = buffer;
    }

    public Producer() {
    }

    @Override
    public void run() {
        String char1="hello";
        for (int i = 0; i < 5; i++) {
            String str = String.valueOf(char1.charAt(i));
            try {
                buffer.write(str);
                System.out.println(Thread.currentThread().getName() + "写入 <--- " + str);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

消费者

/**
 * 消费者,消费产品
 * @author VernHe
 */

public class Consumer implements Runnable{
    private Buffer buffer;

    public Consumer() {
    }

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


    public Buffer getBuffer() {
        return buffer;
    }

    public void setBuffer(Buffer buffer) {
        this.buffer = buffer;
    }


    @Override
    public void run() {
        String c;
        StringBuffer result = new StringBuffer();
        for (int i = 0; i < 5; i++) {
//        for (int i = 0; i < 5; i++) {
            try {
                c = buffer.read();
                result.append(c);
                System.out.println(Thread.currentThread().getName() + "读到 ---> " + c);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.printf("最终读取的结果为:" + result.toString());

    }
}

测试

/**
 * @author VernHe
 */
public class Pv {

    public static void main(String[] args) {
        Buffer buffer = new Buffer();
        Producer producer = new Producer(buffer);
        Consumer consumer = new Consumer(buffer);


        /**
         * 一个生产者一个消费者
         */
        Consumer consumer2 = new Consumer(buffer);
        Thread t1 = new Thread(producer,"Producer_01");
        Thread t2 = new Thread(consumer,"Consumer_01");

        t1.start();
        t2.start();
    }
}

对于实现多个生产者多个消费者,只需要多定义几个生产者消费者对象即可

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

生命中有太多不确定

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值