Java线程生产者和消费者实例

avatar 2017年5月28日20:39:31 评论 88 views

代码如下

  1. package com.liuyanzhao.multi_thread;
  2. /**
  3.  * 注意
  4.  * 1、判断仓库有否有货是否,必须用while,而不能用if,
  5.  * 作用是让线程醒过来的时候,还要判断是否为空,
  6.  * 如果用if的话,就不会判断,直接往下走,
  7.  * 会导致连续生产或者消费。
  8.  * 2、超过两个线程的时候,用notifyAll唤醒,不要用notify
  9.  *
  10.  * @author 言曌
  11.  * @date 2018/6/21 下午5:13
  12.  */
  13. class Resource {
  14.     private boolean isEmpty = true;
  15.     private int count = 0;
  16.     public synchronized void put() { //生产
  17.         //如果不是空,就wait()
  18.         while (!isEmpty) {
  19.             try {
  20.                 wait();//放弃锁,在这里等,本线程暂停
  21.             } catch (InterruptedException e) {
  22.                 e.printStackTrace();
  23.             }
  24.         }
  25.         count++;
  26.         //否则,执行下面代码
  27.         System.out.println(Thread.currentThread().getName() + " 生产1个,剩余" + count + "个");
  28.         isEmpty = false;
  29.         this.notifyAll();//释放锁,所有wait中的线程重新唤醒,开始抢cpu执行权
  30.     }
  31.     public synchronized void get() { //消费
  32.         //如果是空的,就wait()
  33.         while (isEmpty) {
  34.             try {
  35.                 wait();//放弃锁,在这里等,本线程暂停
  36.             } catch (InterruptedException e) {
  37.                 e.printStackTrace();
  38.             }
  39.         }
  40.         count--;
  41.         //否则,执行下面代码
  42.         System.out.println(Thread.currentThread().getName() + " 消费1个,剩余" + count + "个");
  43.         isEmpty = true;
  44.         this.notifyAll();//释放锁,所有wait中的线程重新唤醒,开始抢cpu执行权
  45.     }
  46. }
  47. class Producer implements Runnable {
  48.     private Resource res;
  49.     public Producer(Resource res) {
  50.         this.res = res;
  51.     }
  52.     @Override
  53.     public void run() {
  54.         while (true) {
  55.             res.put();
  56.         }
  57.     }
  58. }
  59. class Consumer implements Runnable {
  60.     private Resource res;
  61.     public Consumer(Resource res) {
  62.         this.res = res;
  63.     }
  64.     @Override
  65.     public void run() {
  66.         while (true) {
  67.             res.get();
  68.         }
  69.     }
  70. }
  71. public class ProducerConsumerDemo {
  72.     public static void main(String[] args) {
  73.         Resource r = new Resource();
  74.         Producer producer = new Producer(r);
  75.         Consumer consumer = new Consumer(r);
  76.         Thread t1 = new Thread(producer, "甲工人");
  77.         Thread t2 = new Thread(producer, "乙工人");
  78.         Thread t3 = new Thread(consumer, "A用户");
  79.         Thread t4 = new Thread(consumer, "B用户");
  80.         t1.start();
  81.         t2.start();
  82.         t3.start();
  83.         t4.start();
  84.     }
  85. }

运行结果

 

注意两点就可以:一个是判断仓库是否有货,用while;另一个是,多线程用notifyAll,不要用notify

本文链接:https://liuyanzhao.com/4465.html

  • 微信
  • 交流学习,有偿服务
  • weinxin
  • 博客/Java交流群
  • 资源分享,问题解决,技术交流。群号:590480292
  • weinxin
avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: