Java生产者消费者模式实现

版本1
import java.util.LinkedList;
import java.util.List;
/**
 * Producer Class in java, Producer will allow consumer to
 * consume only when 10 products have been produced
 * (i.e. when production is over).
 */
class Producer implements Runnable {
   List < Integer > sharedQueue;
   Producer() {
      sharedQueue = new LinkedList < Integer > ();
   }@Override
   public void run() {
      synchronized(this) {
         for (int i = 1; i <= 10; i++) { //Producer will produce 10 products
            sharedQueue.add(i);
            System.out.println("Producer is still Producing, Produced : " + i);
            try {
               Thread.sleep(1000);
            } catch (InterruptedException e) {
               e.printStackTrace();
            }
         }
         System.out.println("Production is over, consumer can consume.");
         //Production is over, notify consumer thread so that consumer can consume.
         this.notify();
      }
   }
}
/**
 * Consumer Class.
 */
class Consumer extends Thread {
   Producer prod;
   Consumer(Producer obj) {
      prod = obj;
   }
   public void run() {
      /*
       * consumer will wait till producer is producing.
       */
      synchronized(this.prod) {
         System.out.println("Consumer waiting for production to get over.");
         try {
            this.prod.wait();
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
      /*production is over, consumer will start consuming.*/
      int productSize = this.prod.sharedQueue.size();
      for (int i = 0; i < productSize; i++)
      System.out.println("CONSUMED : " + this.prod.sharedQueue.remove(0) + " ");
   }
}
public class ProducerConsumerWithWaitNotify {
   public static void main(String args[]) throws InterruptedException {
      Producer prod = new Producer();
      Consumer cons = new Consumer(prod);
      Thread prodThread = new Thread(prod, "prodThread");
      Thread consThread = new Thread(cons, "consThread");
      consThread.start(); //start consumer thread.
      Thread.sleep(100); //This minor delay will ensure that consumer thread starts before producer thread.
      prodThread.start(); //start producer thread.
   }
}

输出
Consumer waiting for production to get over.
Producer is still Producing, Produced : 1
Producer is still Producing, Produced : 2
Producer is still Producing, Produced : 3
Producer is still Producing, Produced : 4
Producer is still Producing, Produced : 5
Producer is still Producing, Produced : 6
Producer is still Producing, Produced : 7
Producer is still Producing, Produced : 8
Producer is still Producing, Produced : 9
Producer is still Producing, Produced : 10
Production is over, consumer can consume.
CONSUMED : 1
CONSUMED : 2
CONSUMED : 3
CONSUMED : 4
CONSUMED : 5
CONSUMED : 6
CONSUMED : 7
CONSUMED : 8
CONSUMED : 9
CONSUMED : 10


版本2
import java.util.LinkedList;
import java.util.List;
/**
 * Producer Class in java, Producer will allow consumer to consume only
 * when 10 products have been produced (i.e. when production is over).
 */
class Producer implements Runnable {
   boolean productionInProcess;
   List < Integer > list;
   Producer() {
      //initially Producer will be producing, so make this productionInProcess true.
      productionInProcess = true;
      list = new LinkedList < Integer > ();
   }@Override
   public void run() {
      for (int i = 1; i <= 10; i++) { //Producer will produce 10 products
         list.add(i);
         System.out.println("Producer is still Producing, Produced : " + i);
         try {
            Thread.sleep(1000);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
      /* Once production is over, make this productionInProcess false.
       * Production is over, consumer can consume.
       */
      productionInProcess = false;
   }
}
/**
 * Consumer Class.
 */
class Consumer extends Thread {
   Producer prod;
   Consumer(Producer obj) {
      prod = obj;
   }
   public void run() {
      /*
       * consumer checks whether productionInProcess is true or not,
       * if it's true, consumer will sleep and wake up after certain time
       * and again check whether productionInProcess is true or false.
       * process will repeat till productionInProcess is true.
       * Once productionInProcess is false we'll exit below while loop.
       */
      while (this.prod.productionInProcess) {
         System.out.println("Consumer waiting for production to get over.");
         try {
            Thread.sleep(4000);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
      /*productionInProcess is false means production is over,
       * consumer will start consuming. */
      System.out.println("Production is over, consumer can consume.");
      int productSize = this.prod.list.size();
      for (int i = 0; i < productSize; i++)
      System.out.println("CONSUMED : " + this.prod.list.remove(0) + " ");
   }
}

public class ProducerConsumerWithoutWaitNotify {
   public static void main(String args[]) {
      Producer prod = new Producer();
      Consumer cons = new Consumer(prod);
      Thread prodThread = new Thread(prod, "prodThread");
      Thread consThread = new Thread(cons, "consThread");
      prodThread.start(); //start producer thread.
      consThread.start(); //start consumer thread.
   }
}

输出
Consumer waiting for production to get over.
Producer is still Producing, Produced : 1
Producer is still Producing, Produced : 2
Producer is still Producing, Produced : 3
Producer is still Producing, Produced : 4
Consumer waiting for production to get over.
Producer is still Producing, Produced : 5
Producer is still Producing, Produced : 6
Producer is still Producing, Produced : 7
Producer is still Producing, Produced : 8
Consumer waiting for production to get over.
Producer is still Producing, Produced : 9
Producer is still Producing, Produced : 10
Production is over, consumer can consume.
CONSUMED : 1
CONSUMED : 2
CONSUMED : 3
CONSUMED : 4
CONSUMED : 5
CONSUMED : 6
CONSUMED : 7
CONSUMED : 8
CONSUMED : 9
CONSUMED : 10

版本3
import java.util.LinkedList;
import java.util.List;
/**
 * Producer Class.
 */
class Producer implements Runnable {
   private List < Integer > sharedQueue;
   private int maxSize = 2; //maximum number of products which sharedQueue can hold at a time.
   public Producer(List < Integer > sharedQueue) {
      this.sharedQueue = sharedQueue;
   }
   @Override
   public void run() {
      for (int i = 1; i <= 10; i++) { //produce 10 products.
         try {
            produce(i);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
   }
   private void produce(int i) throws InterruptedException {
      synchronized(sharedQueue) {
         //if sharedQuey is full wait until consumer consumes.
         while (sharedQueue.size() == maxSize) {
            System.out.println("Queue is full, producerThread is waiting for " + "consumerThread to consume, sharedQueue's size= " + maxSize);
            sharedQueue.wait();
         }
      }
      /* 2 Synchronized blocks have been used means before
       * producer produces by entering below synchronized
       * block consumer can consume.  
       */
      //as soon as producer produces (by adding in sharedQueue) it notifies consumerThread.
      synchronized(sharedQueue) {
         System.out.println("Produced : " + i);
         sharedQueue.add(i);
         Thread.sleep((long)(Math.random() * 1000));
         sharedQueue.notify();
      }
   }
}
/**
 * Consumer Class.
 */
class Consumer implements Runnable {
   private List < Integer > sharedQueue;
   public Consumer(List < Integer > sharedQueue) {
      this.sharedQueue = sharedQueue;
   }
   @Override
   public void run() {
      while (true) {
         try {
            consume();
            Thread.sleep(100);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
   }
   private void consume() throws InterruptedException {
      synchronized(sharedQueue) {
         //if sharedQuey is empty wait until producer produces.
         while (sharedQueue.size() == 0) {
            System.out.println("Queue is empty, consumerThread is waiting for " + "producerThread to produce, sharedQueue's size= 0");
            sharedQueue.wait();
         }
      }
      /* 2 Synchronized blocks have been used means before
       * consumer start consuming by entering below synchronized
       * block producer can produce.  
       */
      /*If sharedQueue not empty consumer will consume
       * (by removing from sharedQueue) and notify the producerThread.
       */
      synchronized(sharedQueue) {
         Thread.sleep((long)(Math.random() * 2000));
         System.out.println("CONSUMED : " + sharedQueue.remove(0));
         sharedQueue.notify();
      }
   }
}
public class ProducerConsumerWaitNotify {
   public static void main(String args[]) {
      List < Integer > sharedQueue = new LinkedList < Integer > (); //Creating shared object
      Producer producer = new Producer(sharedQueue);
      Consumer consumer = new Consumer(sharedQueue);
      Thread producerThread = new Thread(producer, "ProducerThread");
      Thread consumerThread = new Thread(consumer, "ConsumerThread");
      producerThread.start();
      consumerThread.start();
   }
}

输出
Queue is empty, consumerThread is waiting for producerThread to produce, sharedQueue's size= 0
Produced : 1
CONSUMED : 1
Produced : 2
CONSUMED : 2
Produced : 3
Produced : 4
CONSUMED : 3
Produced : 5
Queue is full, producerThread is waiting for consumerThread to consume, sharedQueue's size= 2
CONSUMED : 4
Produced : 6
Queue is full, producerThread is waiting for consumerThread to consume, sharedQueue's size= 2
CONSUMED : 5
Produced : 7
CONSUMED : 6
Produced : 8
Queue is full, producerThread is waiting for consumerThread to consume, sharedQueue's size= 2
CONSUMED : 7
Produced : 9
CONSUMED : 8
Produced : 10
CONSUMED : 9
CONSUMED : 10
Queue is empty, consumerThread is waiting for producerThread to produce, sharedQueue's size= 0

版本4
import java.util.LinkedList;
import java.util.List;
/**
 * Implementing custom BlockingQueue interface .
 * This BlockingQueue implementation follows FIFO (first-in-first-out).
 * New elements are inserted at the tail of the queue,
 * and removal elements is done at the head of the queue.
 */
interface BlockingQueueCustom < E > {
   /**
    * Inserts the specified element into this queue
    * only if space is available else 
    * waits for space to become available.
    */
   void put(E item) throws InterruptedException;
   /**
    * Retrieves and removes the head of this queue
    * only if elements are available else 
    * waits for element to become available.
    */
   E take() throws InterruptedException;
}
/**
 * Implementing custom LinkedBlockingQueue class.
 * This BlockingQueue implementation follows FIFO (first-in-first-out).
 * New elements are inserted at the tail of the queue,
 * and removal elements is done at the head of the queue.
 *
 */
class LinkedBlockingQueueCustom < E > implements BlockingQueueCustom < E > {
   private List < E > queue;
   private int maxSize; //maximum number of elements queue can hold at a time.
   public LinkedBlockingQueueCustom(int maxSize) {
      this.maxSize = maxSize;
      queue = new LinkedList < E > ();
   }
   /**
    * Inserts the specified element into this queue
    * only if space is available else 
    * waits for space to become available.
    */
   public synchronized void put(E item) throws InterruptedException {
      //check space is available or not.
      if (queue.size() == maxSize) {
         this.wait();
      }
      //space is available, insert.
      queue.add(item);
      this.notify();
   }
   /**
    * Retrieves and removes the head of this queue
    * only if elements are available else 
    * waits for element to become available.
    */
   public synchronized E take() throws InterruptedException {
      //waits element is available or not.
      if (queue.size() == 0) {
         this.wait();
      }
      //element is available, remove.
      this.notify();
      return queue.remove(0);
   }
}
/**
 * Producer Class in java
 */
class Producer implements Runnable {
   private final BlockingQueueCustom < Integer > sharedQueue;
   public Producer(BlockingQueueCustom < Integer > sharedQueue) {
      this.sharedQueue = sharedQueue;
   }
   @Override
   public void run() {
      for (int i = 1; i <= 10; i++) {
         try {
            System.out.println("Produced : " + i);
            //put/produce into sharedQueue.
            sharedQueue.put(i);
         } catch (InterruptedException ex) {
         }
      }
   }
}
/**
 * Consumer Class 
 */
class Consumer implements Runnable {
   private BlockingQueueCustom < Integer > sharedQueue;
   public Consumer(BlockingQueueCustom < Integer > sharedQueue) {
      this.sharedQueue = sharedQueue;
   }
   @Override
   public void run() {
      while (true) {
         try {
            //take/consume from sharedQueue.
            System.out.println("CONSUMED : " + sharedQueue.take());
         } catch (InterruptedException ex) {
        }
      }
   }
}
/**
 * Main class
 */
public class ProducerConsumerBlockingQueueCustom {
   public static void main(String args[]) {
      BlockingQueueCustom < Integer > sharedQueue = new LinkedBlockingQueueCustom < Integer > (10); //Creating shared object
      Producer producer = new Producer(sharedQueue);
      Consumer consumer = new Consumer(sharedQueue);
      Thread producerThread = new Thread(producer, "ProducerThread");
      Thread consumerThread = new Thread(consumer, "ConsumerThread");
      producerThread.start();
      consumerThread.start();
   }
}

输出
Produced : 1
Produced : 2
Produced : 3
CONSUMED : 1
Produced : 4
CONSUMED : 2
Produced : 5
CONSUMED : 3
Produced : 6
CONSUMED : 4
Produced : 7
CONSUMED : 5
Produced : 8
CONSUMED : 6
Produced : 9
CONSUMED : 7
Produced : 10
CONSUMED : 8
CONSUMED : 9
CONSUMED : 10


版本5
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
 * Producer Class.
 */
class Producer implements Runnable {
   private final BlockingQueue < Integer > sharedQueue;
   public Producer(BlockingQueue < Integer > sharedQueue) {
      this.sharedQueue = sharedQueue;
   }@Override
   public void run() {
      for (int i = 1; i <= 10; i++) {
         try {
            System.out.println("Produced : " + i);
            //put/produce into sharedQueue.
            sharedQueue.put(i);
         } catch (InterruptedException ex) {
         }
      }
   }
}
/**
 * Consumer Class.
 */
class Consumer implements Runnable {
   private BlockingQueue < Integer > sharedQueue;
   public Consumer(BlockingQueue < Integer > sharedQueue) {
      this.sharedQueue = sharedQueue;
   }@Override
   public void run() {
      while (true) {
         try {
            //take/consume from sharedQueue.
            System.out.println("CONSUMED : " + sharedQueue.take());
         } catch (InterruptedException ex) {}
      }
   }
}
public class ProducerConsumerBlockingQueue {
   public static void main(String args[]) {
      //Creating shared object  
      BlockingQueue < Integer > sharedQueue = new LinkedBlockingQueue < Integer > ();
      Producer producer = new Producer(sharedQueue);
      Consumer consumer = new Consumer(sharedQueue);
      Thread producerThread = new Thread(producer, "ProducerThread");
      Thread consumerThread = new Thread(consumer, "ConsumerThread");
      producerThread.start();
      consumerThread.start();
   }
}

输出
Produced : 1
Produced : 2
CONSUMED : 1
Produced : 3
CONSUMED : 2
Produced : 4
CONSUMED : 3
Produced : 5
CONSUMED : 4
Produced : 6
CONSUMED : 5
Produced : 7
CONSUMED : 6
Produced : 8
CONSUMED : 7
Produced : 9
CONSUMED : 8
Produced : 10
CONSUMED : 9
CONSUMED : 10


版本6
import java.util.concurrent.Exchanger;
public class ExchangerTest {
   public static void main(String[] args) {
      Exchanger < String > exchanger = new Exchanger < String > ();
      System.out.println("Exchanger has been created");
      Producer prod = new Producer(exchanger);
      Consumer cons = new Consumer(exchanger);
      Thread prodThread = new Thread(prod, "prodThread");
      Thread consThread = new Thread(cons, "consThread");
      prodThread.start(); //start producer thread.
      consThread.start(); //start consumer thread.
   }
}
/**
 * Producer Class.
 */
class Producer implements Runnable {
   Exchanger < String > exchanger;
   String str;
   Producer(Exchanger < String > exchanger) {
      str = new String();
      this.exchanger = exchanger;
   }
   @Override
   public void run() {
      for (int i = 1; i <= 5; i++) {
         str += i;
         System.out.println("Produced : " + i);
         try {
            str = exchanger.exchange(str);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
   }
}
/**
 * Consumer Class.
 */
class Consumer extends Thread {
   Producer prod;
   Exchanger < String > exchanger;
   String str;
   Consumer(Exchanger < String > exchanger) {
      this.exchanger = exchanger;
   }
   public void run() {
      for (int i = 0; i < 5; i++) {
         try {
            str = exchanger.exchange(new String());
            System.out.println("CONSUMED : " + str);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
   }
}


输出
Exchanger has been created
Produced : 1
CONSUMED : 1
Produced : 2
CONSUMED : 2
Produced : 3
CONSUMED : 3
Produced : 4
CONSUMED : 4
Produced : 5
CONSUMED : 5


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值