Java多线程-生产者和消费者问题

多生产者,多消费者

if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。

while判断标记,解决了线程获取执行权后,是否要运行!

 

notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+notify会导致死锁。

notifyAll解决了本方线程一定会唤醒对方线程的问题。

 

ProducterConsumer.java

class Resource {

   private String name;
   private int count = 0;
   private boolean flag = false;

   public synchronized void set(String name) {
      while (flag)
        try {
           wait();
    } catch (InterruptedException e) {}
      this.name = name + (++count);
      System.out.println(Thread.currentThread().getName() + "...生产者"+ this.name);
      flag = true;
      notifyAll();
   }

   public synchronized void out() {
      while (!flag)
        try {
           wait();
    } catch (InterruptedException e) {

        }
      System.out.println(Thread.currentThread().getName() + ".........消费者"+ this.name);
      flag = false;
      notifyAll();
   }
}

class Producter implements Runnable {

   private Resource r;
   Producter(Resource r) {
      this.r = r;
   }

   public void run() {
      while (true)
        r.set("烤鸭");
   }
}

class Consumer implements Runnable {
   private Resource r;
   Consumer(Resource r) {
      this.r = r;
   }

   public void run() {
      while (true)
        r.out();
   }
}

class ProducterConsumer {
   public static void main(String[] args) {
      Resource r = new Resource();
      Producter p1 = new Producter(r);
      Producter p2 = new Producter(r);
      Producter p3 = new Producter(r);
      Producter p4 = new Producter(r);
      Consumer c1 = new Consumer(r);
      Consumer c2 = new Consumer(r);
      Consumer c3 = new Consumer(r);
      Consumer c4 = new Consumer(r);
      Thread t0 = new Thread(p1);
      Thread t1 = new Thread(p2);
      Thread t2 = new Thread(p3);
      Thread t3 = new Thread(p4);
      Thread t4 = new Thread(c1);
      Thread t5 = new Thread(c2);
      Thread t6 = new Thread(c3);
      Thread t7 = new Thread(c4);
      t0.start();
      t1.start();
      t2.start();
      t3.start();
      t4.start();
      t5.start();
      t6.start();
      t7.start();
   }
}

单生产者单消费者

Productor.java

public class Productor extends Thread {

   private PCUtil pcu;

   public Productor(PCUtil pcu) {
      super();
      this.pcu = pcu;
   }

   public void run() {
      while (true) {
        pcu.product();
        try {
           Thread.sleep(200);
    } catch (InterruptedException e) {
           e.printStackTrace();
        }
      }
   }
}

Consumer.java

public class Consumer extends Thread {
   private PCUtil pcu;

   public Consumer(PCUtil pcu) {
      super();
      this.pcu = pcu;
   }

   public void run() {
      while (true) {
        pcu.consume();
        try {
           Thread.sleep(200);
    } catch (InterruptedException e) {
           e.printStackTrace();
        }
      }
   }

}

PCUtil.java

import java.util.Random;
public class PCUtil {
   private int[] arr = new int[3];
   private int count = 0;// 用来记录数组中数据的个数
   private Random r = new Random();

   /**
    * 生产一个数据
    */
   public synchronized void product() {
      try {
        if (count < arr.length) {
       // 可以生产数据
           int num = r.nextInt(20) + 1;
           System.out.println("生产:" + num);
           arr[count] = num;
           count++;
           notify();
    } else {
           // 说明数组装满了
           System.out.println("生产者进入休眠");
           this.wait();
        }
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
   }

   /**
    * 消费一个数据
    */
   public synchronized void consume() {
      try {
        if (count > 0) {
           System.out.println("消费:" + arr[--count]);
           notify();
    } else {
           System.out.println("消费者进入休眠");
           this.wait();
        }
      } catch (Exception e) {
      }
   }
}

Test.java

public class Test {  public static void main(String[] args) {
      PCUtil util = new PCUtil();
      Productor productor = new Productor(util);
      Consumer consumer = new Consumer(util);
      productor.start();
      consumer.start();
   }
}