概论
举个例子:有一个固定容量的货架,生产者放商品进来,消费者拿商品出去,为了保证正常放入和正常拿出(数据的正确性,不会出现超过容量的存放,拿到空气)。使用同步块中的 wait 和 notifAll 方法进行控制。
形如
synchronized (被锁的对象) { 被锁的对象.wait(); //线程进入阻塞状态,把锁住的资源打开。 被锁的对象.notifyAll(); //通知其它所有的线程取消阻塞状态。 }
商品
//商品 class Love{ static String love="love"; public String toString(){ //所有商品都是love! return love; } }
货架
//货架 class Shelves{ List goods;//商品 int VOLUME=10;//容量 public Shelves(List goods) { this.goods = goods; } }
生产者
//生产者 class Producer implements Runnable{ Shelves shelves;//货架 int count;//商品的数量 //使用的货架 public Producer(Shelves shelves) { this.shelves = shelves; } //生产商品到放到货架 public void run() { //一直在生产 while (true) { //获取货架上的商品个数 count=shelves.goods.size(); synchronized (shelves) { if (count > shelves.VOLUME) { System.out.println("货架放不下了,暂停制作"); try { //货架资源放出去 shelves.wait(); } catch (InterruptedException e) { e.printStackTrace(); } }else { System.out.println("【生产者】:现在这里有"+count+"个商品"); System.out.println("努力制作了1个商品"); System.out.println("---------------------"); //生产一个商品 shelves.goods.add(new Love()); //有商品了,告知wait的消费者可以来消费了 shelves.notifyAll(); try { //每0.5秒做一个 Thread.sleep(500); } catch (Exception e) { e.printStackTrace();} } } } } }
消费者
//消费者 class Consumer implements Runnable{ Shelves shelves;//货架 int count;//商品的数量 public Consumer(Shelves shelves){ this.shelves=shelves; } //消费者从货架取走商品 public void run() { //每过2秒取走最后一个 while (true) { count=shelves.goods.size(); synchronized (shelves) { if (count == 0) { System.out.println("【消费者】:货架没有商品了,等等吧,等他做出来在买。"); try { shelves.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else { //买到一个 System.out.println("【消费者】:买到1个商品,看看里面什么!----->"+(shelves.goods.get(count-1)).toString()); shelves.goods.remove(--count); System.out.println("【消费者】:现在这里还有"+shelves.goods.size()+"个商品"); System.out.println("---------------------"); //通知制作 shelves.notifyAll(); try { //每两秒消费一个商品 Thread.sleep(2000); } catch (Exception e) { e.printStackTrace();} } } } } }
测试:
public class LeaningThread { public static void main(String[] args) { //初始化货架,0个商品 List<Love> list = new ArrayList<>(); Shelves sl = new Shelves(list); //开启生产者线程 new Thread(new Producer(sl)).start(); //开启消费者线程 new Thread(new Consumer(sl)).start(); } }
运行结果(手动结束程序运行):
注意
wait和notifyAll:必须在synchronized方法或块中使用,通过被锁的对象进行调用。
标签:count,货架,goods,Java,shelves,生产者,并发,商品,println From: https://www.cnblogs.com/lurenjia-bky/p/16884666.html