关于生产者与消费者的例子

import java.util.Vector;

public class SyncTest {
 public static void main(String[] args){
  SyncTest t = new SyncTest();

  final SyncTest.SyncStack ss = t.new SyncStack();

  Runnable Producer = new Runnable() {
   private char c = 'a';
   public void run() {
    try {
     while(c != 'j') {
      Thread.sleep(500); //生产时间间隔
      System.out.println("produce=" + c);
      ss.push(c++);
     }
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  };

  Runnable Consumer = new Runnable() {
   public void run() {
    int i = 9;
    try {
     while(i-- > 0) {
      Thread.sleep(1000); //消费时间间隔
      System.out.println("consume=" + ss.pop());
     }
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  };
  new Thread(Producer).start();
  new Thread(Consumer).start();
 }
 /**
 * 一个栈,相当于商店,
 * 总是把最先生产的商品消费掉。
 */

 class SyncStack {

  private Vector<Character> stack;

  public SyncStack() {
   stack = new Vector<Character>(100); //可容纳100件商品
  }

  public synchronized void push(char c) {
   stack.add(c);
   //一旦线程被释放并可随后再次获得栈的锁,
   //该线程就可以继续执行pop()完成从栈缓冲区中移走字符任务的代码。
   //对this.notify()的调用将释放一个因栈空而调用wait()的单个线程。
   //在共享数据发生真正的改变之前调用notify()不会产生任何结果。
   //只有退出该synchronized块后,才会释放对象的锁,所以当栈数据在被改变时,正在等待锁的线程不会获得这个锁。

   this.notify();
  }

  public synchronized char pop() {
   char c;
   while(stack.size() == 0) {
    try {
     //wait()方法在对栈的共享数据作修改之前被调用。
     //这是非常关键的一点,因为在对象锁被释放和线程继续执行改变栈数据的代码之前,数据必须保持一致的状态。
     //必须使所设计的代码满足这样的假设:在进入影响数据的代码时,共享数据是处于一致的状态。

     this.wait();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
   c = stack.remove(stack.size() - 1);
   return c;
  }
 }
}



/**
* 一个空的盒子,一次只能把一个物品放进去,一次也只能拿出一个盒子
*/

public class TestGoodsBox {
 public static void main(String[] args) {
  final GoodsBox box = new GoodsBox();

  Runnable a = new Runnable() {
   public void run() {
    int i = 10;
    try {
     while(i-- > 0) {
      Thread.sleep(500);
      String goods = "goods-" + i;
      System.out.println(Thread.currentThread().getName() +  "put in " + goods);
      box.putIn(goods);
     }
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  };

  Runnable b = new Runnable() {
   public void run() {
    int i = 10;
    while(i-- > 0) {
     Object goods = box.takeOut();
     System.out.println(Thread.currentThread().getName() +  "took out " + goods);
    }
   }
  };
  new Thread(a).start();
  new Thread(b).start();
 }
}
/**
* 物品盒子类
*/

class GoodsBox {

 private Object o;

 public  C() {
  this.o = null; //null表示盒子为空
 }

 public synchronized void putIn(Object goods) {
  while(this.o != null) {
   try {
    this.wait(); //盒子被占用处于等待状态
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
  this.o = goods; //放入物品
  this.notify(); //通知盒子为满
 }

 public synchronized Object takeOut() {
  while(o == null) {
   try {
    this.wait(); //盒子为空时等待
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
  Object goods = this.o;
  this.o = null; //取出物品
  this.notify(); //通知盒子为空
  return goods;
 }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值