Java多线程之生产消费模型

目录

生产消费模型基本概念

问题描述

解决方法

wait()

notify()

 notifyAll()

 具体例子

生产者类:

消费者类:

商品类:

测试类:

ProductionConsumptionFinal 


生产消费模型基本概念

生产消费模型就是通过一个容器来解决生产者与消费者之间的强耦合问题,我们大家都去超市消费过,我们作为消费者,在不断的消费,而是超市就是那个生产者,我们与超市之间存在的所谓容器其实就是货架,当货架空的时候,我们作为消费者就不能在消费了。当货架满的时候,超市作为生产者就不能在生产了。 

问题描述

生产与消费的速度不匹配

解决方法

wait()

会让执行该方法的当前的线程进入等待状态

Java多线程之生产消费模型

 举个例子:

public class TestWait implements Runnable{      private final Object object = new Object();      @Override     public void run() {          synchronized (object){              System.out.println("线程执行开始.....");              try {                  object.wait();              } catch (InterruptedException e) {                  e.printStackTrace();              }              System.out.println("线程执行结束.....");          }     }     public static void main(String[] args){         TestWait testWait = new TestWait();         Thread thread = new Thread(testWait);         thread.start();     } }

测试结果:

Java多线程之生产消费模型

 可以看出这个线程调用wait()方法之后就会进入等待状态,一直在运行,且不会中断。除非让这个线程接受唤醒操作或者中断操作

notify()

唤醒被wait()的线程,如果有多个线程被wait()随机唤醒一个

Java多线程之生产消费模型

 notify()调用后不会立即释放锁,而是当执行notify()的线程执行完成,即退出同步代码块才会释放掉锁。

举个列子:

public class TestWait implements Runnable{      private final Object object = new Object();      public void setFlag(boolean flag){         this.flag = flag;     }      private boolean flag = true;      @Override     public void run() {         if(flag){             this.testwait();         }else {             this.testnotify();         }     }      public void testwait(){         synchronized (object){             try {                 System.out.println("线程开始执行");                 Thread.sleep(1000);                 object.wait();             } catch (InterruptedException e) {                 e.printStackTrace();             }             System.out.println("线程执行结束");         }     }      public void testnotify(){         synchronized (object){             try {                 Thread.sleep(1000);             } catch (InterruptedException e) {                 e.printStackTrace();             }             object.notify();         }     }      public static void main(String[] args){         TestWait testWait = new TestWait();         Thread thread = new Thread(testWait);         thread.start();         try {             Thread.sleep(1000);         } catch (InterruptedException e) {             e.printStackTrace();         }         testWait.setFlag(false);         Thread thread1 = new Thread(testWait);         thread1.start();     } }

测试结果:

Java多线程之生产消费模型

 notifyAll()

唤醒所有被wait()的线程

Java多线程之生产消费模型

举个例子:

public class TestWait implements Runnable{      private final Object object = new Object();      private boolean flag = true;      public void setFlag(boolean flag){         this.flag = flag;     }     @Override     public void run() {         if(flag){             this.testwait();         }else{             this.testnotify();         }     }     public void testwait(){         synchronized (object){             try {                 System.out.println(Thread.currentThread().getName()+"线程开始执行");                 Thread.sleep(1000);                 object.wait();             } catch (InterruptedException e) {                 e.printStackTrace();             }             System.out.println(Thread.currentThread().getName()+"线程执行结束");         }     }     public void testnotify(){         synchronized (object){             try {                 Thread.sleep(1000);             } catch (InterruptedException e) {                 e.printStackTrace();             }             object.notifyAll();         }     }     public static void main(String[] args){         TestWait testWait = new TestWait();         Thread thread = new Thread(testWait,"线程1");         thread.start();         Thread thread1 = new Thread(testWait,"线程2");         thread1.start();         try {             Thread.sleep(2000);         } catch (InterruptedException e) {             e.printStackTrace();         }         testWait.setFlag(false);         Thread thread2 = new Thread(testWait);         thread2.start();     } } 

测试结果:

Java多线程之生产消费模型

 具体例子

这个例子当中,我们会写四个类,生产者类消费者类商品类测试类

生产者类:

/**  * 生产者类  */ public class Producer implements Runnable{      private Goods goods;      private TestPC tp;      @Override     public void run() {             while (true){                 try {                     Thread.sleep(2000);                 } catch (InterruptedException e) {                     e.printStackTrace();                 }                 synchronized (TestPC.queue){                     goods = new Goods(1,"商品");                     if(TestPC.queue.size()<tp.MAX_POOL){                         TestPC.queue.add(goods);                         System.out.println(Thread.currentThread().getName()+"生产商品");                     }else {                         try {                             TestPC.queue.wait();                         } catch (InterruptedException e) {                             e.printStackTrace();                         }                     }                  }             }      } }

消费者类:

/**  * 消费者类  */ public class Consumer implements Runnable{      @Override     public void run() {         while (true){             try {                 Thread.sleep(2000);             } catch (InterruptedException e) {                 e.printStackTrace();             }             synchronized (TestPC.queue){                 if(!TestPC.queue.isEmpty()){                     TestPC.queue.poll();                     System.out.println(Thread.currentThread().getName()+"消费商品");                 }else {                     TestPC.queue.notify();                 }             }         }      } }

商品类:

/**  * 商品类  */ public class Goods {     private int id;     private String name;      public Goods(int id,String name){         this.id = id;         this.name = name;     } } 

测试类:

import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue;  /**  * 测试类  */ public class TestPC {     public static final int MAX_POOL = 10;     public static final int MAX_PRODUCER = 5;     public static final int MAX_CONSUMER = 4;      public static Queue<Goods> queue = new ArrayBlockingQueue<>(MAX_POOL);     public static void main(String[] args){         Producer producer = new Producer();         Consumer consumer = new Consumer();         for(int i = 0;i<MAX_PRODUCER;i++){             Thread threadA = new Thread(producer,"生产者线程"+i);             threadA.start();         }         for(int j = 0;j<MAX_CONSUMER;j++){             Thread threadB = new Thread(consumer,"消费者线程"+j);             threadB.start();         }     } }

测试结果:

Java多线程之生产消费模型

这个可能不是那么清晰,但是原理就是这么个原理。接下来的版本可能就会比较清晰!

ProductionConsumptionFinal 

public class Test1 {     private static Integer count = 0;     private static final Integer FULL = 10;     private static String LOCK = "lock";      public static void main(String[] args) {         Test1 test1 = new Test1();         new Thread(test1.new Producer()).start();         new Thread(test1.new Consumer()).start();         new Thread(test1.new Producer()).start();         new Thread(test1.new Consumer()).start();         new Thread(test1.new Producer()).start();         new Thread(test1.new Consumer()).start();         new Thread(test1.new Producer()).start();         new Thread(test1.new Consumer()).start();     }      class Producer implements Runnable{          @Override         public void run() {              for (int i = 0;i<10;i++){                  try {                      Thread.sleep(3000);                  } catch (InterruptedException e) {                      e.printStackTrace();                  }                  synchronized (LOCK){                      while (count == FULL){                          try {                              LOCK.wait();                          } catch (InterruptedException e) {                              e.printStackTrace();                          }                      }                      count++;                      System.out.println(Thread.currentThread().getName()+"生产者生产,目前共有"+count);                      LOCK.notifyAll();                  }              }         }     }      class Consumer implements Runnable{          @Override         public void run() {             for (int i = 0;i<10;i++){                 try {                     Thread.sleep(3000);                 } catch (InterruptedException e) {                     e.printStackTrace();                 }                 synchronized (LOCK){                     while(count == 0){                         try {                             LOCK.wait();                         } catch (InterruptedException e) {                             e.printStackTrace();                         }                     }                     count--;                     System.out.println(Thread.currentThread().getName()+"消费者消费,目前共有"+count);                     LOCK.notifyAll();                 }             }         }     } } 

测试结果:

Java多线程之生产消费模型

 好了这就是Java中的生产消费模型,在面试中也常考的问题。

版权声明:玥玥 发表于 2021-08-18 11:13:55。
转载请注明:Java多线程之生产消费模型 | 女黑客导航