`

wait notify 对象锁

阅读更多

通常,多线程之间需要协调工作。例如,浏览器的一个显示图片的线程displayThread想要执行显示图片的任务,必须等待下载线程 downloadThread将该图片下载完毕。如果图片还没有下载完,displayThread可以暂停,当downloadThread完成了任务 后,再通知displayThread“图片准备完毕,可以显示了”,这时,displayThread继续执行。
以上逻辑简单的说就是:如果条件不满足,则等待。当条件满足时,等待该条件的线程将被唤醒。在Java中,这个机制的实现依赖于wait/notify。等待机制与锁机制是密切关联的。例如:
synchronized(obj) {while(!condition) {obj.wait();}obj.doSomething();}  

当线程A获得了obj锁后,发现条件condition不满足,无法继续下一处理,于是线程A就wait()。
在另一线程B中,如果B更改了某些条件,使得线程A的condition条件满足了,就可以唤醒线程A:
synchronized(obj) {condition = true;obj.notify();} 

需要注意的概念是:
◆调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) {...} 代码段内。
◆调用obj.wait()后,线程A就释放了obj的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj) {...} 代码段内唤醒A。
◆当obj.wait()方法返回后,线程A需要再次获得obj锁,才能继续执行。
◆如果A1,A2,A3都在obj.wait(),则B调用obj.notify()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM决定)。
◆obj.notifyAll()则能全部唤醒A1,A2,A3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,A1,A2,A3只有一个有机会获得锁继续执行,例如A1,其余的需要等待A1释放obj锁之后才能继续执行。
◆当B调用obj.notify/notifyAll的时候,B正持有obj锁,因此,A1,A2,A3虽被唤醒,但是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后,A1,A2,A3中的一个才有机会获得锁继续执行。

 

 

 

生产者:

package com.shejimoshi;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * Title: 生产者
 * </p>
 * 
 * <p>
 * Description: 
 * </p>
 * 
 * <p>
 * Copyright: 融博技术有限公司 2013
 * </p>
 * 
 * @author 袁泉锋HO174959
 * @version 1.0
 * @date Mar 14, 2013
 *
 */
public class Threada extends Thread {
	private List list;
	public Threada(List list){
		this.list = list;
	}
	@Override
	public void run() {
		while (true) {
			synchronized (list) {
				if (list.size() > 4) {
					try {
						list.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				} 
				list.add("1");
				list.notify();
				System.out.println("已经增加到:" + list.size());
			}
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
	}
	public static void main(String[] args) {
		List l = new ArrayList();
		Threada a = new Threada(l);
		Threadb b = new Threadb(l);
		a.start();
		b.start();
	}
}

 消费者:

package com.shejimoshi;

import java.util.List;

/**
 * <p>
 * Title: 消费者
 * </p>
 * 
 * <p>
 * Description: 
 * </p>
 * 
 * <p>
 * Copyright: 融博技术有限公司 2013
 * </p>
 * 
 * @author 袁泉锋HO174959
 * @version 1.0
 * @date Mar 14, 2013
 *
 */
public class Threadb extends Thread {
	private List list;
	public Threadb(List list){
		this.list = list;
	}
	@Override
	public void run() {
		while (true) {
			synchronized (list) {
				if (list.size() == 0) {
					try {
						list.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				} 
				list.remove(0);
				list.notify();
				System.out.println("取了还剩下:" + list.size());
			}
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
	}
	
}

 结果:

已经增加到:1
取了还剩下:0
已经增加到:1
取了还剩下:0
已经增加到:1
已经增加到:2
已经增加到:3
取了还剩下:2
已经增加到:3
取了还剩下:2
已经增加到:3
已经增加到:4
已经增加到:5
取了还剩下:4
已经增加到:5
取了还剩下:4
已经增加到:5
取了还剩下:4
已经增加到:5

 

分享到:
评论

相关推荐

    锁、生产者与消费者.pdf

    注意:上述方法只能被同步监听锁对象来调用,这也是为啥wait() 和 notify()方法都在 Object 对象中,因为同步监听锁可以是任意对象,只不过必须是需要同步线程的共同对象即可,否则别的对象调用会报错:  java.lang...

    100家大公司java笔试题汇总

    wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。) sleep...

    jsp内置对象的用法

    7 void notify() 唤醒一个等待的线程 8 void notifyAll() 唤醒所有等待的线程 9 void wait(int timeout) 使一个线程处于等待直到timeout结束或被唤醒 10 void wait() 使一个线程处于等待直到被唤醒 11 void...

    java笔试题大集合及答案(另附各大公司笔试题)

    wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。 62、同步和...

    面试专题-并发篇讲义.pdf

    新建 当一个线程对象被创建,但还未调用 start 方法时处于新建状态 此时未与操作系统底层线程关联 可运行 调用了 start 方法,就会由新建进入可运行 ...当其它持锁线程调用 notify() 或 notifyAll() 方法,会按照一

    计算机等级考试二级java经典例题

    共享数据的状态并不一定满足线程的需要,它要等待其他线程将共享数据改变为它需要的状态后才能继续执行,但由于此时它占有了该对象的锁,其他线程无法对共享数据进行操作,为此Java引入wait()和notify(),...

    Java-线程状态和等待唤醒机制和线程池

    1.概念 线程一共有6中状态,相互之间可以互相转换。 等待唤醒案例(线程之间的通信) 实现: 等待唤醒案例:线程之间的通信 ... 只有锁对象才能调用wait和notify方法 Obejct类中的方法 void wait

    java线程学习笔记

    一 基本知识 2 1.1 任务Runnable 2 ...2.4.3 对象锁不可用 17 2.4.4 通过wait()使线程挂起。 17 2.5 线程合作(wait || notifyAll) 21 2.5.1 Wait()两种形式 21 2.5.2 互斥的实现 22 2.5.3 notify()与notifyAll() 24

    Day 22多线程、线程通信、线程池和Lambda表达式

    Day 22 Author:ScorpioDong 1. 多线程 ...进入锁对象抢占过程,有可能进入锁阻塞状态 2. 线程通信 现在存在两个完全无关的线程,生产者和消费者,但是商品会作为他们两者之间的共享资源。 生产者和消费

    超级有影响力霸气的Java面试题大全文档

    wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。 17、...

    python多线程高级锁condition简单用法示例

    – wait:线程挂起,收到notify通知后继续运行 – notify:通知其他线程, 解除其它线程的wai状态 – notifyAll(): 通知所有线程 – acquire和release: 获得锁和解除锁, 与lock类似, – enter和exit使得对象支持上...

    python条件变量之生产者与消费者操作实例分析

    互斥锁是最简单的线程同步机制,面对复杂线程同步问题,Python还提供了Condition对象。Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还提供了wait和notify方法。线程首先acquire一个条件...

    jstack生成的Thread Dump日志.docx

    只有当别的线程在该对象上调用了 notify()或者notifyAll()方法,"Wait Set"队列中的线程才得到机会去竞争,但是只有一个线程获得对象的Monitor,恢复到运行态。"Wait Set"中的线程在Thread Dump中显示的状态为 in ...

    第22天

    notify() / notifyAll() 不仅能唤醒无限等待状态线程,还能开启【锁对象】。 如果是生产者与消费者的情况时,若wait()方法不在同步代码块中,则会产生丢失唤醒的骚操作,即生产者生产完成时,还未做出wait等待时,被...

    Python线程条件变量Condition原理解析

    这篇文章主要介绍了Python线程条件变量Condition原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的...wait() 会释放这个锁,阻塞本线程直到其他线程通过 notify() 或 notify_all() 来唤醒它。

    多线程,线程通信,线程池和Lambda表达式

    多线程,线程通信,线程池和Lambda表达式 1. 多线程 1.1 线程状态 WAITING... 唤醒和当前锁对象有关的无限等待线程中的一个,随机选择。 1. 唤醒一个无限等待状态线程 2. 开启【锁对象】 public void notif

    Python threading模块condition原理及运行流程详解

    Condition的处理流程如下: 首先acquire一个条件变量,然后判断一些条件。...线程通过acquire获得Condition对象,当调用wait方法时,线程会释放Condition内部的锁并进入blocked状态,同时在waiting池中记录这个线

    UNIX网络编程 卷2:进程间通信

     10.3 sem_wait和sem_trywait函数 180  10.4 sem_post和sem_getvalue函数 180  10.5 简单的程序 181  10.6 生产者-消费者问题 186  10.7 文件上锁 190  10.8 sem_init和sem_destroy函数 191  10.9 多个生产者...

    Java面试题.docx

    41、谈谈wait/notify关键字的理解 42、什么导致线程阻塞?线程如何关闭? 43、如何保证线程安全? 44、如何实现线程同步? 45、线程间操作List 46、谈谈对Synchronized关键字,类锁,方法锁,重入锁的理解 49...

    JAVA面试题集合面试技能大全

    Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。 5. 请讲一讲析构函数和虚函数的用法和作用。 6. Error与Exception有什么区别? Error表示系统级的错误和...

Global site tag (gtag.js) - Google Analytics