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();
    }
}

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

猜你喜欢

转载自blog.csdn.net/weixin_44829930/article/details/109338882