`
825197453
  • 浏览: 101096 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

生产者与消费者

阅读更多
public class MainThread
{
    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        Queue queue = new Queue(); //定义缓冲区;
        Producer producer = new Producer(queue); //生产者
        Consumer consumer = new Consumer(queue); //消费者
        new Thread(producer).start();
        new Thread(consumer).start();
    }
}

/*注意:wait notify notifyAll只能在同步方法或同步块中调用*/
class Queue   //queue表示队列
{
    int product = 0;
    
    boolean bfull = false;
    
    public synchronized void setProduct(int product)
    {
        if (bfull)//如果队列已满,则调用wait等待消费者取走产品
        {
            try
            {
                wait();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        /*开始放置产品到队列中*/
        this.product = product;
        System.out.println("Producer set product:" + product);
        bfull = true;
        notify();//生产产品后通知消费者取走产品
    }
    
    public synchronized void getProduct()
    {
        if (!bfull)//如果队列是空的,则调用wait等待生产者生产产品
        {
            try
            {
                wait();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        /*开始从队列取走产品*/
        System.out.println("Consumer get product:" + product);
        bfull = false;
        notify();//取走产品后通知生产者继续生产产品
    }
}

class Producer implements Runnable
{
    Queue queue;
    
    Producer(Queue queue)
    {
        this.queue = queue;
    }
    
    public void run()//生产线程
    {
        for (int i = 1; i <= 10; i++)
        {
            queue.setProduct(i);
        }
    }
}

class Consumer implements Runnable
{
    Queue queue;
    
    Consumer(Queue queue)
    {
        this.queue = queue;
    }
    
    public void run()//消费线程
    {
        for (int i = 1; i <= 10; i++)
        {
            queue.getProduct();
        }
    }
}





/* 
 * Java 生产者-消费者案例框架
 *“生产者-消费者”问题的含义是,
 *系统中有很多生产者和消费者并
 *发工作生产者负责生产资源,消费者消耗资源。
 *当消费者消费资源时,如果资源不足,则需要等待,
 *反之当生产者生产资源时,若资源已满,则也需要等待。
 *另外同一时刻只能有一个生产者或消费者进行操作。 
 */

//面包容器(资源)      
class BreadContainer
{
    // 容器的最大容量   
    public static final int maxNum = 300;
    
    // 当前面包的数量   
    private int num;
    
    // 无参构造器   
    public BreadContainer()
    {
    }
    
    // 有参构造器   
    public BreadContainer(int num)
    {
        // 初始化面包数量   
        this.num = num;
    }
    
    // 制作面包的同步方法   
    public synchronized void produceBread(int produceNum, String ProducerSName)
    {
        // 测试是否可以生产面包   
        while (num + produceNum > maxNum)
        {
            // 面包充足,生产者等待   
            System.out.println(ProducerSName + "要生产" + produceNum + "个,当前" + num
                    + "个,资源充足,不需要生产," + ProducerSName + "去等待!");
            try
            {
                wait();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        // 满足条件后,生产者生产面包,刷新数量   
        num = num + produceNum;
        System.out.println(ProducerSName + "生产了" + produceNum + "个,现在有" + num
                + "个。");
        // 唤醒资源等待池中的所有线程   
        notifyAll();
    }
    
    public synchronized void consumeBread(int consumeNum, String ConsumerSName)
    {
        // 测试面包数量是否够消费   
        while (consumeNum > num)
        {
            // 不够数量,消费者等待   
            System.out.println(ConsumerSName + "要消费" + consumeNum + "个,由于现在只有"
                    + num + "个," + ConsumerSName + "于是去等待!");
            try
            {
                wait();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        // 数量充足,消费面包,刷新数量   
        num = num - consumeNum;
        System.out.println(ConsumerSName + "消费了" + consumeNum + "个,现在还剩下" + num
                + "个");
        // 唤醒资源等待池中的所有线程   
        this.notifyAll();
    }
}

// 生产者类   
class ProducerS extends Thread
{
    // 记录该生产者一次生产的数量   
    private int produceNum;
    
    // 生产者需要访问的面包容器资源   
    private BreadContainer bc;
    
    // 无参构造器   
    public ProducerS()
    {
    }
    
    // 有参构造器   
    public ProducerS(int produceNum, BreadContainer bc, String ProducerSName)
    {
        // 对线程进行初始化   
        this.produceNum = produceNum;
        this.bc = bc;
        this.setName(ProducerSName);
    }
    
    // 生产者的工作方法   
    public void run()
    {
        // 调用资源容器的同步方法生产资源   
        bc.produceBread(produceNum, this.getName());
    }
}

// 消费者类   
class ConsumerS extends Thread
{
    // 记录该消费者一次消费的数量   
    private int consumeNum;
    
    // 消费者需要访问的面包容器资源   
    private BreadContainer bc;
    
    // 无参构造器   
    public ConsumerS()
    {
    }
    
    // 有参构造器   
    public ConsumerS(int consumeNum, BreadContainer bc, String ConsumerSName)
    {
        // 对线程进行初始化   
        this.consumeNum = consumeNum;
        this.bc = bc;
        this.setName(ConsumerSName);
    }
    
    // 消费者的行为方法   
    public void run()
    {
        // 调用资源容器的同步方法生产资源   
        bc.consumeBread(consumeNum, this.getName());
    }
}

public class Sample16_9
{
    public static void main(String args[])
    {
        // 创建资源对象,初始面包有50个   
        BreadContainer bc = new BreadContainer(50);
        // 创建对应的生产者和消费者   
        ProducerS p1 = new ProducerS(50, bc, "P1");
        ProducerS p2 = new ProducerS(200, bc, "P2");
        ProducerS p3 = new ProducerS(290, bc, "P3");
        ConsumerS c1 = new ConsumerS(70, bc, "c1");
        ConsumerS c2 = new ConsumerS(80, bc, "c2");
        // 启动生产者消费者线程   
        c1.start();
        c2.start();
        p1.start();
        p3.start();
        p2.start();
    }
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics