java 与操作系统进程同步问题(二)————经典消费者生产者问题

时间:2021-11-09 20:20:09

http://www.cnblogs.com/zyp4614/p/6033757.html  

(java 与操作系统进程同步问题(一)————互斥问题)

 

 

  今天写的是最经典的生产者消费者问题,最简单的版本,即只有一个缓冲区,缓冲区中只能放一个物品,即不考虑互斥关系。

   问题简单分析: 生产者在缓冲区为空的时候可以往缓冲区中放产品,消费者可以在缓冲区不空(即缓冲区中有产品时)可以取一个产品。

  

   首先可以确定有两个信号量

   第一个信号量,是缓冲区是否空,当空的时候生产者可以放入产品,初值为1,因为默认缓冲区是空的

   第二个信号量,是缓冲区是否满,当满的时候消费者可以取出产品,初值为0,因为开始缓冲区内没有产品

 

 

     /**
     * 代表缓冲区是否空
     */
    Semaphore empty;
    
    /**
     * 代表缓冲区是否满
     */
    Semaphore full;

 

 

   生产者伪代码如下

 

 

wait(empty)

//放入产品


signal(full)

 

 

   消费者伪代码如下:

wait(full)


//取产品


signal(empty)

 

   类实现如下

public class ProductAndVistor {
    Thread producer = new Thread(new Runnable() {
        
        @Override
        public void run() {
            String className = "producer";
            // TODO Auto-generated method stub
            while(true) {
                Semaphore.Wait(empty, className);
                System.out.println(className + "往缓冲区放了一个产品");
                //随机生成休眠时间,代表放入产品的操作时间
                long millis = (long) (Math.random() * 1000);
                try {
                    Thread.sleep(millis);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Semaphore.Signal(full, className);
            }
            
        }
        
    });
    
    Thread vistor = new Thread(new Runnable() {
        String className = "vistor";
        @Override
        public void run() {
            // TODO Auto-generated method stub
            while(true) {
                Semaphore.Wait(full, className);
                System.out.println(className + "从缓冲区取了一个产品");
                long millis = (long) (Math.random() * 1000);
                try {
                    Thread.sleep(millis);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Semaphore.Signal(empty, className);
            }
        }
    });
    
    /**
     * 代表缓冲区是否满
     */
    Semaphore empty;
    
    /**
     * 代表缓冲区是否空
     */
    Semaphore full;
    
    public ProductAndVistor(Semaphore s1, Semaphore s2) {
        this.empty = s1;
        this.full = s2;
    }
    
    public ProductAndVistor() {
        empty = new Semaphore(1);
        full = new Semaphore(0);
    }
    
    public void start() {
        producer.start();
        vistor.start();
    }
    
}