[转载]生产者/消费者模式

转载 2013年12月04日 18:33:00

生产者/消费者模式 
        生产者/消费者模式其实是一种很经典的线程同步模型,很多时候,并不是光保证多个线程对某共享资源操作的互斥性就够了,往往多个线程之间都是有协作的。
        假设有这样一种情况,有一个桌子,桌子上面有一个盘子,盘子里只能放一颗鸡蛋,A专门往盘子里放鸡蛋,如果盘子里有鸡蛋,则一直等到盘子里没鸡蛋,B专门 从盘子里拿鸡蛋,如果盘子里没鸡蛋,则等待直到盘子里有鸡蛋。其实盘子就是一个互斥区,每次往盘子放鸡蛋应该都是互斥的,A的等待其实就是主动放弃锁,B 等待时还要提醒A放鸡蛋。
如何让线程主动释放锁
很简单,调用锁的wait()方法就好。wait方法是从Object来的,所以任意对象都有这个方法。看这个代码片段:

Java代码  收藏代码
  1. Object lock=new Object();//声明了一个对象作为锁  
  2.    synchronized (lock) {  
  3.        balance = balance - num;  
  4.        //这里放弃了同步锁,好不容易得到,又放弃了  
  5.        lock.wait();  
  6. }  
 


如果一个线程获得了锁lock,进入了同步块,执行lock.wait(),那么这个线程会进入到lock的阻塞队列。如果调用 lock.notify()则会通知阻塞队列的某个线程进入就绪队列。
声明一个盘子,只能放一个鸡蛋

 
Java代码  收藏代码
  1. import java.util.ArrayList;  
  2. import java.util.List;  
  3.   
  4. public class Plate {  
  5.   
  6.     List<Object> eggs = new ArrayList<Object>();  
  7.   
  8.     public synchronized Object getEgg() {  
  9.         while(eggs.size() == 0) {  
  10.             try {  
  11.                 wait();  
  12.             } catch (InterruptedException e) {  
  13.             }  
  14.         }  
  15.   
  16.         Object egg = eggs.get(0);  
  17.         eggs.clear();// 清空盘子  
  18.         notify();// 唤醒阻塞队列的某线程到就绪队列  
  19.         System.out.println("拿到鸡蛋");  
  20.         return egg;  
  21.     }  
  22.   
  23.     public synchronized void putEgg(Object egg) {  
  24.         while(eggs.size() > 0) {  
  25.             try {  
  26.                 wait();  
  27.             } catch (InterruptedException e) {  
  28.             }  
  29.         }  
  30.         eggs.add(egg);// 往盘子里放鸡蛋  
  31.         notify();// 唤醒阻塞队列的某线程到就绪队列  
  32.         System.out.println("放入鸡蛋");  
  33.     }  
  34.       
  35.     static class AddThread extends Thread{  
  36.         private Plate plate;  
  37.         private Object egg=new Object();  
  38.         public AddThread(Plate plate){  
  39.             this.plate=plate;  
  40.         }  
  41.           
  42.         public void run(){  
  43.             for(int i=0;i<5;i++){  
  44.                 plate.putEgg(egg);  
  45.             }  
  46.         }  
  47.     }  
  48.       
  49.     static class GetThread extends Thread{  
  50.         private Plate plate;  
  51.         public GetThread(Plate plate){  
  52.             this.plate=plate;  
  53.         }  
  54.           
  55.         public void run(){  
  56.             for(int i=0;i<5;i++){  
  57.                 plate.getEgg();  
  58.             }  
  59.         }  
  60.     }  
  61.       
  62.     public static void main(String args[]){  
  63.         try {  
  64.             Plate plate=new Plate();  
  65.             Thread add=new Thread(new AddThread(plate));  
  66.             Thread get=new Thread(new GetThread(plate));  
  67.             add.start();  
  68.             get.start();  
  69.             add.join();  
  70.             get.join();  
  71.         } catch (InterruptedException e) {  
  72.             e.printStackTrace();  
  73.         }  
  74.         System.out.println("测试结束");  
  75.     }  
  76. }  

相关文章推荐

阻塞队列实现生产者消费者模式

生产者消费者模式是并发、多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据。这篇文章我们来看看什么是生产者消费者模式,这个问...

生产者 消费者 模式 c++

  • 2014-04-25 07:25
  • 19KB
  • 下载

生产者—消费者模式的两种同步实现

简要问题描述 一组生产者进程和一组消费者进程共享一个初始为空、大小为n的缓冲区,只有缓冲区没满时,生产者才能把消息放入到缓冲区,否则必须等待;只有缓冲区不空时,消费者才能从中取出消息,否则必须等待。由...

Java 生产者消费者模式

  • 2015-10-22 17:43
  • 10KB
  • 下载

Java线程(三):线程协作-生产者/消费者模式

上一篇讲述了线程的互斥(同步),但是在很多情况下,仅仅同步是不够的,还需要线程与线程协作(通信),生产者/消费者模式是一个经典的线程同步以及通信的模型。         假设有这样一种情况,有一个盘...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)