`
yydcj
  • 浏览: 59939 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

一个notify()的实例分析

阅读更多

在java多线程编程中,就要涉及到了对于资源的访问,当多个线程同时访问一个资源的时候就要涉及到一种访问策略。java提供了锁的机制,就是一个线程访问这个资源的时候可以先把这个资源锁住可以用synchronized(the object)来锁定the object,其他访问这个资源的线程就进入阻塞状态,直到当前的线程执行了这个对象的notify或者notifyall其他访问这个对象的阻塞状态的线程才有可能变成就绪状态。其中notify是唤醒一个线程,而notifyall是唤醒所有阻塞进程。

如下是一个这方面的实例

 

package concurrent;

import java.util.concurrent.TimeUnit;
/**
 * Wait、Notify、NotifyAll的区别
 * @author yydcj
 * Email:yydcj@163.com
 * 网址:<a>http://yydcj.iteye.com</a>
 */
public class WaitNotify {
	private static int reduceThreadCount =0;
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		WaitNotify notify = new WaitNotify();
		Source source = notify.new Source("source");
		
		for (int i = 0; i < 10; i++)
			notify.new ReduceThread(source).start();
//		try {
//			TimeUnit.SECONDS.sleep(5);
//		} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
		notify.new AddThread(source).start();
	}
	class ReduceThread extends Thread{

		private Source source;
		public ReduceThread(Source source){
			super("ReduceThread-" + reduceThreadCount++);
			this.source = source; 
		}
		public void run(){
			for (int i = 0; i < 10; i++){
				try {
					TimeUnit.SECONDS.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				source.reduceCount();
			}
		}
	}
	class AddThread extends Thread{
		private Source source;
		public AddThread(Source source){
			super("AddThread");
			this.source = source; 
		}
		public void run(){
			for (int i = 0; i < 1; i++){
				try {
					TimeUnit.SECONDS.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				source.addCount();
			}
		}
	}
	class Source{
		private int count = 0;
		public Source(String name){
//			this.name = name;
		}
		public synchronized void addCount() {
			System.out.println(Thread.currentThread().getName()+": count+1="+ ++count);
			notify();			
		}
		public synchronized void reduceCount() {
			while (count <= 0) {
				try {
					System.out.println(Thread.currentThread().getName()+" wait()");
					wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(Thread.currentThread().getName()+": count-1="+ --count);
		}
	}
}

 //output:

ReduceThread-1 wait()
ReduceThread-5 wait()
ReduceThread-8 wait()
ReduceThread-6 wait()
ReduceThread-4 wait()
ReduceThread-2 wait()
ReduceThread-0 wait()
AddThread: count+1=1
ReduceThread-7: count-1=0
ReduceThread-9 wait()
ReduceThread-3 wait()
ReduceThread-1 wait()
ReduceThread-7 wait()

 

我这里是用notify()来唤醒其中一个ReduceThread线程的(此时notify的是ReduceThread-7),然后ReduceThread-7执行完消费任务后又进入了wait()、10个reduce线程虽然是顺序实例化的,但是他们并不是顺序拿到souce对象的。 依次拿到souce对象的1586420 这7个线程,各个线程因为count 为0释放了这个对象给其他的线程。 然后AddThread拿到了这个对象,将count变为1,notify了一个线程,这个线程就是1 。虽然1被notify了,但是他并没有取得对象,对象被7获取了并将count设置为0,所以等于说1这个线程醒来之后发现count依然为0,所以又wait了一遍

一个线程被notify之后并不认为已经获取了对象,依然需要去和其他线程抢对象才能继续执行下去。

 

 

 

 

1
0
分享到:
评论
2 楼 yydcj 2010-11-26  
hadesmile 写道
10个reduce线程虽然是顺序实例化的,但是他们并不是顺序拿到souce对象的。

根据楼主的例子,依次拿到souce对象的1586420 这7个线程,然后各个线程因为count 为0释放了这个对象给其他的线程。
然后AddThread拿到了这个对象,将count变为1,notify了一个线程,这个线程就是1
虽然1被notify了,但是他并没有取得对象,对象被7获取了并将count设置为0,所以等于说1这个线程醒来之后发现count依然为0,所以又wait了一遍

一个线程被notify之后并不认为已经获取了对象,依然需要去和其他线程抢对象才能继续执行下去。



1楼正解,是我的失误,呵呵
1 楼 hadesmile 2010-11-26  
10个reduce线程虽然是顺序实例化的,但是他们并不是顺序拿到souce对象的。

根据楼主的例子,依次拿到souce对象的1586420 这7个线程,然后各个线程因为count 为0释放了这个对象给其他的线程。
然后AddThread拿到了这个对象,将count变为1,notify了一个线程,这个线程就是1
虽然1被notify了,但是他并没有取得对象,对象被7获取了并将count设置为0,所以等于说1这个线程醒来之后发现count依然为0,所以又wait了一遍

一个线程被notify之后并不认为已经获取了对象,依然需要去和其他线程抢对象才能继续执行下去。

相关推荐

    WM_NOTIFY消息流程实例分析

    WM_NOTIFY消息流程实例分析---对应博客代码

    php进行支付宝开发中return_url和notify_url的区别分析

    本文实例分析了php进行支付宝开发中return_url和notify_url的区别。分享给大家供大家参考。具体分析如下: 在支付宝处理业务中return_url,notify_url是返回些什么状态呢,我们要根据它来做一些处理就必须了解return_...

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

    线程首先acquire一个条件变量,然后判断一些条件。如果条件不满足则wait;如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,其他处于wait状态的线程接到通知后会重新判断条件。不断的重复这一...

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

     SessionBean: Stateless Session Bean 的生命周期是由容器决定的,当客户机发出请求要建立一个Bean的实例时,EJB容器不一定要创建一个新的Bean的实例供客户机调用,而是随便找一个现有的实例提供给客户机。...

    java 面试题 总结

    然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中...

    vue逐行注释分析+40多m的vue源码程序流程图思维导图

    ob___属性并且是不是Obersve实例化的,value是不是Vonde实例化的,如果不是则调用Obersve去把数据添加到观察者中,为数据添加__ob__属性,Obersve则调用defineReactive方法,该方法是连接Dep和wacther方法的一个通道...

    java多线程通信之等待唤醒机制

    典型实例有生产者和消费者,本文也通过实例来分析线程等待唤醒机制。  1、相关API介绍  public final void notify()  唤醒在此对象监视器上等待的单个线程,如果所有线程都在此对象上等待,则会任意选择唤醒...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    对Java语言的每个语法都提供了一个或多个例程讲解 大量使用流程图表示程序的执行过程,使用结构图表示程序的内部状态 每章最后都给出了典型的练习题,让读者及时练习,巩固提高,并提供了参考答案 目录 第1篇 ...

    javaSE代码实例

    1.4 第一个Java程序 8 1.4.1 开发源代码 8 1.4.2 编译运行 9 1.5 小结 11 第2章 基本数据类型——构建Java 大厦的基础 12 2.1 源代码注释 12 2.1.1 单行注释 12 2.1.2 区域注释 12 2.1.3 文档...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    对Java语言的每个语法都提供了一个或多个例程讲解 大量使用流程图表示程序的执行过程,使用结构图表示程序的内部状态 每章最后都给出了典型的练习题,让读者及时练习,巩固提高,并提供了参考答案 目录 第1篇 ...

    C++MFC教程

    数组中每一个元素为CString对象的实例。下面介绍几个成员函数: Add 增加CString RemoveAt 删除指定位置CString对象 RemoveAll 删除数组中所有CString对象 GetAt 得到指定位置的CString对象 SetAt 修改指定位置...

    基于SIP开发软件电话的一些资源(转自YOUTOO)

    在VC里创建win32控制台程序工程,将libosip源码包的SRC目录下的Test目录内的C源程序随便拷一个到工程时,直接编译(工程设置里照前文方法在link选项里增加osip2.lib,osipparser2.lib引用我们之前成功编译得到的静态...

    php微信支付之APP支付方法

    本文实例讲述了微信开放平台移动应用集成微信支付功能。分享给大家供大家参考。具体分析如下: WechatAppPay文件代码如下: 复制代码 代码如下: &lt;?php namespace common\services\WechatPay; class WechatAppPay ...

    Python RuntimeError: thread.__init__() not called解决方法

    在写一个多线程类的时候调用报错 RuntimeError: thread.__init__() not called 复制代码 代码如下: class NotifyTread(threading.Thread):   def __init__(self, params):   threading.Thread.__init__(self) ...

    UML基础、案例与应用(第三版)].施穆勒.扫描版_2分.pdf

    12.3.1 在UML 1.x和UML 2.0中表示一个构件 135 12.3.2 接口表示法 136 12.3.3 黑盒和白盒 137 12.4 应用构件图 137 12.5 UML“大图”中的构件图 141 12.6 小结 142 12.7 常见问题解答 142 12.8 小测验和习题 143 ...

    外文翻译 stus MVC

    This stateless behavior made it difficult for the model to notify the view of changes. On the Web, the browser has to re-query the server to discover modification to the state of the application. ...

    java基础案例与开发详解案例源码全

    2.3.3 开发Java第一个程序21 2.3.4 Java代码中的注释23 2.3.5 常见错误解析24 2.4 Java类库组织结构和文档27 2.5 Java虚拟机简介28 2.6 Java技术两种核心运行机制29 2.7 上机练习30 第3章 3.1 变量32 3.1.1 什么是...

    JAVA程序设计教程

    §1.3 一个完整的 Java程序.............................................................................................6 1.3.1 Java程序的结构 .........................................................

    JAVA核心知识点整理(有效)

    可达性分析............................................................................................................................................... 26 2.3.2. 2.3.3. 老年代 ........................

Global site tag (gtag.js) - Google Analytics