notify()与wait()
先来说一下notify()、notifyAll()与wait()方法.
可能会令初学者可能比较困惑的是,作为线程通讯的方式,notify()、notifyAll()与wait()却被定义在Object类上。其实很好理解,wait()的本质是释放已获取的锁对象并阻塞等待被唤醒,而notify()则是释放已获取的锁对象并唤醒在wait()中等待同一个锁的线程。因此调用方式便是
[锁对象].wait()
或者
[锁对象].notify().
若不指明调用对象,实际上就用this关键字代替了[锁对象],即当前对象本身作为锁对象。
若调用上述代码时并未获取任何锁,或者指定的锁对象和获取的锁不符,都会抛出 java.lang.IllegalMonitorStateException 生产者者与消费者
生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据。
需要如下三部分组成:
1.存储对象:即图中的Shared Buffer。存储对象中防止生产者的产品,同时让消费者消费。
2.生产者,负责生产商品并添加至存储对象。当存储放满时停止生产。当生产完一个产品时,通知消费者消费。 注意,这里容易产生一个误解:通知消费者消费,并不代表消费者一定会去消费。有可能还未进入消费的代码块时,CPU又可能由于分时的工作原理,放下消费者转而继续执行生产者。又或者可能有多个生产者同时生产。
3.消费者,负责消费商品。当存储对象中商品为空时等待。
实现方式,根据线程通讯操作所处位置,可分为如下两种:
(一) 在消费者和生产者中完成线程通讯
public class Repository { //仓储类 private LinkedList<Object> repository = new LinkedList<Object>(); //仓储实现 private int MAX = 10; //最大商品数量 private int count=0; //当前商品数量 public boolean add(Object product){ count++; return this.repository.add(product); } public Object remove(){ count--; return this.repository.removeLast(); } public int getMAX() { return MAX; } public int getCount() { return count; } }
public class Producer implements Runnable{ private Repository repository; public Repository getRepository() { return repository; } public void setRepository(Repository repository) { this.repository = repository; } public Producer(Repository repository){ this.repository=repository; } @Override public void run() { while (true) { synchronized (repository) { try { while (repository.getCount()==repository.getMAX()) { //当商品数量已满时,暂停生产 System.out.println("respositry is full , please wait"); repository.wait(); } Object newOb = new Object(); if (repository.add(newOb)) { //生成商品,并唤醒所有该锁的等待者 System.out.println("Producer put a Object to respositry"); Thread.sleep((long) (Math.random() * 3000)); repository.notifyAll(); } } catch (InterruptedException ie) { System.out.println("producer is interrupted!"); } } } }
public class Consumer implements Runnable{ public Repository respository; public Repository getRespository() { return respository; } public void setRespository(Repository respository) { this.respository = respository; } public Consumer(Repository repository){ this.respository=repository; } @Override public void run() { while (true) { synchronized (respository) { try { while (respository.getCount() == 0) { //当商品为空时,暂停消费 System.out.println("repositry is empty , please wait"); respository.wait(); } respository.remove(); //消费商品 System.out.println("Comsumer get a Object from repositry"); Thread.sleep((long) (Math.random() * 3000)); respository.notifyAll(); } catch (InterruptedException ie) { System.out.println("Consumer is interrupted"); } } } } }
public class Client { public static void main(String[] args) { Repository repository=new Repository(); new Thread(new Producer(repository)).start(); new Thread(new Consumer(repository)).start(); } }
相关推荐
Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 Java线程:volatile关键字 Java线程:新特征-线程池 Java线程:新特征-有返回值的线程 Java线程:新特征-锁(上) Java线程:新特征-锁(下) Java...
学习Java线程之并发协作生产者消费者模型.pdf
Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 Java线程:volatile关键字 Java线程:新特征-线程池 Java线程:新特征-有返回值的线程 Java线程:新特征-锁(上) Java线程:新特征-锁(下) ...
Java线程:概念与原理 2 一、操作系统中线程和进程的概念 2 二、Java中的线程 3 三、Java中关于线程的名词解释...Java线程:并发协作-生产者消费者模型 52 Java线程:并发协作-死锁 55 Java线程:线程之间的数据传递 58
Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 Java线程:volatile关键字 Java线程:新特征-线程池 Java线程:新特征-有返回值的线程 Java线程:新特征-锁(上) Java线程:新特征-锁(下) Java...
生产者-消费者 设计模式参考《大话设计模式》 工厂简单模式 创造型模式 工厂方法模式 抽象工厂模式 原型模式 建造者模式 单例模式 结构型模式 队列模式 桥接模式 组合模式 装饰模式 外观模式 享元模式 代理模式 行为...
生产者与消费者进程共享一个大小固定的缓冲区。其中,一个或多个生产者生产数据,并将生产的数据存入缓冲区,并有一个或多个消费者从缓冲区中取数据。 2、 系统设计: 系统的设计必须要体现进程之间的同步关系,...
生产者如果不释放对临界资源的占用权,那么 消费者就无法消费队列中的商品 ,就不会让队列有空间,那么生产者就会一直无限等待下去。因此,一般情况下,当队列满时,会让生产者交出对临界资源的占用权,并进入挂起...
作业二:生产者消费者问题。 要求: (1)生产者与消费者均为独立的线程。 (2)生产者与消费者之间有条不紊的协作进行数据的生产和消费。
重命名 实验三多:线程同步与协作:生产者与消费者 为 实验三:多线程同步与协作:生产者与消费者 实验九:使用jdbc存取大文本 add 实验九:使用jdbc存取大文本. 实验二:多线程打字游戏 add 实验二:多线程...
Java线程指南 线程安全与不安全 线程同步synchronized和volatile 线程协作-生产者/消费者模式 Timer和TimerTask 线程池 Callable和Future 锁对象Lock-同步问题更完美的处理方式 Condition-线程通信更高效的方式
Thread_study04:多线程_线程协作_生产者消费者模式,管程法,信号灯法,定时调度,单例模式,Threadlocal,可重入锁,CAS
生产者和消费者是一个十分经典的多线程协作模式 **常见方法:** - void wait() 当前线程等待,直到被其他线程唤醒 - void notify() 随机唤醒单个线程 - void notifyAll() 唤醒所有线程
1)演示简单的消费者和生产者的例子: 17 2)管道的读写流处理方式 19 3)重要的演示死锁的问题—哲学家就餐问题 20 4)终止多线程程序的两种方式(轮询访问变量和interrupt方法) 23 四Concurrent包详解 25 1)Executor...
状态图——Java线程类Thread uml/activity_bug.mdl //06.活动图——Bug管理系统 uml/activity_atm.mdl //06.活动图——ATM机存取款 uml/activity_thread.mdl //06.活动图——Java线程类Thread uml/sequence_bug.mdl ...
状态图——Java线程类Thread uml/activity_bug.mdl //06.活动图——Bug管理系统 uml/activity_atm.mdl //06.活动图——ATM机存取款 uml/activity_thread.mdl //06.活动图——Java线程类Thread uml/sequence_...
状态图——Java线程类Thread uml/activity_bug.mdl //06.活动图——Bug管理系统 uml/activity_atm.mdl //06.活动图——ATM机存取款 uml/activity_thread.mdl //06.活动图——Java线程类Thread uml/sequence_bug.mdl ...
状态图——Java线程类Thread uml/activity_bug.mdl //06.活动图——Bug管理系统 uml/activity_atm.mdl //06.活动图——ATM机存取款 uml/activity_thread.mdl //06.活动图——Java线程类Thread uml/sequence_...