zoukankan      html  css  js  c++  java
  • Java 生产者模式 消费者模式

    1 // The standard idiom for calling the wait
    2 synchronized(sharedObject) {
    3        while(condition){
    4             sharedObject.wait();// Releases lock, and reacquires on wake up
    5        }
    6        // do action based upon condition e.g. take or put into queue        
    7 }

    使用wait和notify函数的规范代码模版。

    在while循环里使用wait的目的:是在线程被唤醒前后都持续检查条件是否被满足,如果条件并未改变,wait被调用之前notify的唤醒通知就来了,那个这个线程并不能保证被唤醒,有坑会导致死锁的问题。

     1 public class ProducerConsumer {
     2       public static void main (String args[]) {
     3             Queue<Integer> buffer = new LinkedList<>();
     4             int maxSize = 10;
     5             Thread producer = new Producer(buffer, maxSize, "PRODUCER");          
     6             Thread consumer = new Producer(buffer, maxSize, "CONSUMER");
     7             producer.start();
     8             consumer.start();
     9       }  
    10 }    

    在上面代码中,声明了一个LinkedList作为缓冲区队列(在java中,LinkedList实现了队列的接口)。

    class Producer extends Thread  {
          private Queue<Integer> queue;
          private int maxSize;
          public Producer(Queue<Integer> queue, int maxSize, String name) {
                 super(name);
                 this.queue = queue;
                 this.maxSize = maxSize;
          }
           
          @Override
          public void run () {
               while (true) {
                     synchronized (queue) {  // 其它线程不能在我们检查条件时改变这个队列
                            while (queue.size() == maxSize) {
                                  try {
                                        // Queue is full 
                                        // Producer thread waiting for
                                        // consumer to take something from queue
                                        queue.wait();
                                  } catch (Exception e) {
                                        e.printStackTrace();
                                  }
                                  Random random = new Random();
                                  int producerValue = random.nextInt();
                                  queue.add(producerValue);
                                  queue.notifyAll();
                            }
                     }
               }
          }
    }

    如上代码为生产者,其在无限循环中持续往LinkedList里插入随机整数直到LinkedList满。如果队列满了,那么生产者线程会在消费者线程消耗掉队列里的任意一个整数,并用notify通知生产者线程之前持续等待。

     1 class Consumer extends Thread {
     2     private Queue<Integer> queue;
     3     private int maxSize;
     4     public Consumer (Queue<Integer> queue, int maxSize, String name ){
     5          super(name);
     6          this.queue = queue;  
     7          this.maxSize= maxSize;  
     8     }  
     9     @Override
    10     public void run() {
    11           while (true) {
    12                 synchronized (queue) {
    13                       while (queue.isEmpty()) {
    14                              // queue is empty;
    15                              // Consumer thread is waiting
    16                              // for producer thread to put something in queue
    17                              try {
    18                                    queue.wait();
    19                              } catch (Exception e) {
    20                                    e.printStackTrace();
    21                              }
    22                              print("Consumer value : " + queue remove());
    23                              queue.notifyAll();
    24                       }
    25                 }
    26           }
    27     }
    28 }

    注意:

    1. 你可以使用wait和notify函数来实现线程间通信,你可以用它们来实现多线程之间的通信。

    2. 永远在synchronized的函数或者对象里使用wait、notify、notifyAll,不然java虚拟机会生成IllgalMonitorStateException。

    3. 永远在while循环里而不是在if语句下使用wait,这样,循环会在线程睡眠前后都检查wait的条件,并在条件实际上并未改变的情况下处理唤醒通知。

    4. 永远在多线程间共享的对象(生产者消费者模型里即缓冲区队列)上使用wait。

    Producer - Consumer Pattern:

    Consumer:

    sunchronized (obj) {
         while (!workToDo) {
               obj.wait();
         }
         // get next item from this queue
         workToDo = false;
    }
    // do work on the item

    Producer:

    1 synchronized (obj) {
    2       if (!workToDo) {
    3            // add work to queue
    4            workToDo = true;
    5       }
    6       obj.notifyAll();
    7 }
  • 相关阅读:
    React `${}` 格式
    echarts-for-react
    React 列表 瀑布流 修改样式瀑布流不起效果
    前端技术栈
    React 技术栈
    自定义点击body 退出登录url隐藏
    import 'element-ui/lib/theme-default/index.css'报错
    cnpm install element-ui --save
    Vue http://eslint.org/docs/rules/no-trailing-spaces 报错问题
    【loj 6363】地底蔷薇【拉格朗日反演】【生成函数】
  • 原文地址:https://www.cnblogs.com/CharlesGrant/p/4756787.html
Copyright © 2011-2022 走看看