使用Lock来实现生产者和消费者问题

.Net技术 码拜 11年前 (2013-05-19) 1422次浏览 0个评论
生产者-消费者(producer-consumer)问题,也称作有界缓冲区(bounded-buffer)问题,两个进程共享一个公共的固定大小的缓冲区。其中一个是生产者,用于将消息放入缓冲区;另外一个是消费者,用于从缓冲区中取出消息。问题出现在当缓冲区已经满了,而此时生产者还想向其中放入一个新的数据项的情形,其解决方法是让生产者此时进行休眠,等待消费者从缓冲区中取走了一个或者多个数据后再去唤醒它。同样地,当缓冲区已经空了,而消费者还想去取消息,此时也可以让消费者进行休眠,等待生产者放入一个或者多个数据时再唤醒它。
package com.thread;
 import java.util.LinkedList;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 /**
  * 使用Lock来实现生产者和消费者问题
  *
  * @author 刘玲
  *
  */
 public class ProducerConsumer {
     public static void main(String[] args) {
         Basket b = new Basket();
         Product p = new Product(b);
         Consumer c = new Consumer(b);
         Consumer c1 = new Consumer(b);
         new Thread(p).start();
         new Thread(c).start();
         new Thread(c1).start();
     }
 }
 //馒头
 class ManTou{
     int id;
     public ManTou(int id) {
         this.id = id;
     }
     @Override
     public String toString() {
         return “ManTou”+id;
     }
 }
 //装馒头的篮子
 class Basket{
     int max = 6;
     LinkedList<ManTou> manTous = new LinkedList<ManTou>();
     Lock lock = new ReentrantLock(); //锁对象
     Condition full = lock.newCondition();  //用来监控篮子是否满的Condition实例
     Condition empty = lock.newCondition(); //用来监控篮子是否空的Condition实例
     //往篮子里面放馒头
     public void push(ManTou m){
         lock.lock();
         try {
             while(max == manTous.size()){
                 System.out.println(“篮子是满的,待会儿再生产…”);
                 full.await();
             }
             manTous.add(m);
             empty.signal();
         } catch (InterruptedException e) {
             e.printStackTrace();
         }finally{
             lock.unlock();
         }
     }
     //往篮子里面取馒头
     public ManTou pop(){
         ManTou m = null;
         lock.lock();
         try {
             while(manTous.size() == 0){
                 System.out.println(“篮子是空的,待会儿再吃…”);
                 empty.await();
             }
             m = manTous.removeFirst();
             full.signal();
         } catch (InterruptedException e) {
             e.printStackTrace();
         }finally{
             lock.unlock();
             return m;
         }
     }
 }
 //生产者
 class Product implements Runnable{
     Basket basket;
     public Product(Basket basket) {
         this.basket = basket;
     }
     public void run() {
         for (int i = 0; i < 40; i++) {
             ManTou m = new ManTou(i);
             basket.push(m);
             System.out.println(“生产了”+m);
             try {
                 Thread.sleep((int)(Math.random()*2000));
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
     }
 }
 //消费者
 class Consumer implements Runnable{
     Basket basket;
     public Consumer(Basket basket) {
         this.basket = basket;
     }
     public void run() {
         for (int i = 0; i < 20; i++) {
             try {
                 Thread.sleep((int)(Math.random()*2000));
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
             ManTou m = basket.pop();
             System.out.println(“消费了”+m);
         }
     }
 }
原文博客:http://home.cnblogs.com/u/liuling/

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明使用Lock来实现生产者和消费者问题
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!