一个简单的生产者-消费者 模型

时间:2021-10-03 14:56:12
/*
 * 生产者消费者案例:
 */
public class TestProductorAndConsumerForLock {

    public static void main(String[] args) {
        Clerk clerk = new Clerk();

        Productor pro = new Productor(clerk);
        Consumer con = new Consumer(clerk);

        new Thread(pro, "生产者 A").start();
        new Thread(con, "消费者 B").start();
    }

}

class Clerk {
    private int product = 0;

    private Lock lock = new ReentrantLock();
    private Condition notFull = lock.newCondition();
    private Condition notEmpty = lock.newCondition();

    // 进货
    public void get() {
    	while(true){
    		 lock.lock();
    		 
    	        try {
    	            if (product >= 10) { // 为了避免虚假唤醒,应该总是使用在循环中。
    	                System.out.println("产品已满!");
    	                try {
    						notFull.await();//生产者阻塞 让给消费者执行
    					} catch (InterruptedException e) {
    						// TODO Auto-generated catch block
    						e.printStackTrace();
    					}
    	                

    	            }
    	            System.out.println(Thread.currentThread().getName() + " : 存货"
    	                    + ++product);
    	            notEmpty.signal();//唤醒消费者
    	            
    	        } finally {
    	            lock.unlock();
    	        }
    	}
       

    }

    // 卖货
    public void sale() {
    	while(true){
    		 lock.lock();

    	        try {
    	            if (product <= 0) {
    	                System.out.println("缺货!");

    	                try {
    	                    notEmpty.await();//消费者阻塞 让给生产者执行
    	                    //替代this.wait;
    	                } catch (InterruptedException e) {
    	                }
    	            }

    	            System.out.println(Thread.currentThread().getName() + " :余货 "
    	                    + --product);

    	            notFull.signal();//唤醒 生产者
    	            //代替this.notifyall();

    	        } finally {
    	            lock.unlock();
    	        }
    	    }
    	}
       
}

// 生产者
class Productor implements Runnable {

    private Clerk clerk;

    public Productor(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            clerk.get();
        }
    }
}

// 消费者
class Consumer implements Runnable {

    private Clerk clerk;

    public Consumer(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            clerk.sale();
        }
    }

}