Condition的生产者消费者的实现

298 阅读2分钟

这里是要作为Condition实现生产者与消费者的示例代码。要学习Condition的原理与实现,可以看这篇文章 : www.jianshu.com/p/cab88918d…

//生产者
public class ThreadATest extends Thread{

    private ProdAndCustService prodAndCustService;

    public ThreadATest(ProdAndCustService prodAndCustService) {
        super();
        this.prodAndCustService=prodAndCustService;
    }

    @Override
    public void run() {
        prodAndCustService.set();
    }
}

//消费者
public class ThreadB extends Thread{

    private ProdAndCustService prodAndCustService;

    public ThreadB(ProdAndCustService prodAndCustService) {
        super();
        this.prodAndCustService=prodAndCustService;
    }

    @Override
    public void run() {
        prodAndCustService.get();
    }
}

//生产与消费服务具体实现
public class ProdAndCustService {

    //厨师同时煮饭的人数,生产者
    volatile private Semaphore setSemaphore = new Semaphore(10);

    //消费者,同时吃饭的人
    volatile private Semaphore getSemaphore = new Semaphore(20);

    volatile private ReentrantLock lock = new ReentrantLock();

    volatile private Condition setCondition = lock.newCondition();

    volatile private Condition getCondition = lock.newCondition();
    //定义装产品的盘子只有四个
    volatile private Object[] producePosition = new Object[4];
    
    private boolean isFull() {
        boolean full = true;
        for (int i = 0; i < producePosition.length; i++) {
            if (producePosition[i] == null) {
                full = false;
                break;
            }
        }
        return full;
    }

    private boolean isEmpty() {
        boolean empty = true;
        for (int i = 0; i < producePosition.length; i++) {
            if (producePosition[i] != null) {
                empty = false;
                break;
            }
        }
        return empty;
    }

    /** 生产多个菜*/
    public void set(){

        try{
            //获取允许信号
            setSemaphore.acquire();
            //加锁
            lock.lock();
            while(isFull()) {
//                System.out.println("厨师开始等待等待。。。");
                setCondition.await();
            }

            for(int i=0;i<producePosition.length;i++){
                if(producePosition[i]==null){
                    producePosition[i]="蛋炒饭";
                    System.out.println("厨师"+Thread.currentThread().getName()+"做了一份菜");
                    break;
                }
            }
            getCondition.signalAll();
            lock.unlock();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            setSemaphore.release();
        }
    }

    //模拟客户吃饭
    public void get(){

        try {
            //客户获取允许信号
            getSemaphore.acquire();
            //获取后在加锁
            lock.lock();

            while(isEmpty()){
                //没有菜了,客户需要等待
//                System.out.println("客户开始等待上菜,盘子没有菜了。。。");
                //执行等待
                getCondition.await();
            }

            for(int i=0;i<producePosition.length;i++){

                if(producePosition[i]!=null){
                    System.out.println(Thread.currentThread().getName()+"客户开始吃饭消费。。。。");
                    producePosition[i]=null;
                    break;
                }
            }
            //有客户消费了,就让厨师继续执行
            setCondition.signalAll();
            lock.unlock();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            //释放一个允许
            getSemaphore.release();
        }
    }

    public Object[] getProducePosition() {
        return producePosition;
    }

    public void setProducePosition(Object[] producePosition) {
        this.producePosition = producePosition;
    }
}

//测试类
public class RunTest {
    public static void main(String[] args) throws InterruptedException {
        ThreadATest[] produce=new ThreadATest[60];
        ThreadB[] consumer=new ThreadB[60];
        ProdAndCustService prodAndCustService=new ProdAndCustService();
        for(int i=0;i<60;i++){
            produce[i]=new ThreadATest(prodAndCustService);
            consumer[i]=new ThreadB(prodAndCustService);
        }
        Thread.sleep(1000);
        for(int i=0;i<60;i++){
            produce[i].start();
            consumer[i].start();
        }
    }
}

总共120个线程,分别是厨师60个与客户60个。