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

转载 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. }  

生产者/消费者模式(转载)

★简介     在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象地称为...

生产者/消费者模式(转载)

生产者/消费者模式[0]:概述   今天打算来介绍一下“生产者/消费者模式”,这玩意儿在很多开发领域都能派上用场。由于该模式很重要,打算分几个帖子来介绍。今天这个帖子先来扫盲一 把。如果你对这个模...

生产者消费者模式+定时任务demo

  • 2017年04月12日 12:05
  • 34KB
  • 下载

架构设计 生产者消费者模式

  • 2015年05月06日 19:36
  • 130KB
  • 下载

NSCondition实现生产者消费者模式

使用NSCondition对象来控制进程的同步,通过NSCondition对象的操作实现进程间的通信。NSCondition也实现了NSLocking协议,因此也可以调用lock、 unlock来实现...
  • codebat
  • codebat
  • 2014年11月11日 11:20
  • 1396

生产者 消费者 模式 c++

  • 2014年04月25日 07:25
  • 19KB
  • 下载

Java 生产者消费者模式

  • 2015年10月22日 17:43
  • 10KB
  • 下载

Java并行编程-lock中使用多条件condition(生产者消费者模式实例)

Java 并发包下的提供Lock,Lock相对于Synchronized可以更好的解决线程同步问题,更加的灵活和高效,并且ReadWriteLock锁还能实现读、写的分离。但线程间仅仅互斥是不够的,还...

生产者和消费者模式多线程

  • 2017年07月26日 09:57
  • 2KB
  • 下载

Qt C++11 生产者消费者模式类

  • 2017年07月11日 21:56
  • 2KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[转载]生产者/消费者模式
举报原因:
原因补充:

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