`
yydcj
  • 浏览: 61546 次
  • 性别: 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消息流程实例分析

    在Windows应用程序开发中,`WM_NOTIFY`消息是一个至关重要的部分,它在父窗口和子窗口之间提供了通信的桥梁。这个消息主要用于控件向其父窗口报告事件,例如当用户与控件交互时,如点击按钮、选择列表项等。通过深入...

    一个理解wait()与notify()的例子

    ### 一个理解wait()与notify()的例子 #### 知识点概述 本文旨在解析一个具体的Java多线程示例代码,以帮助读者更好地理解`wait()`与`notify()`方法的作用及其实现机制。这两个方法是Java中实现线程间通信的重要...

    gcd简介及应用实例及实例分析.txt

    ### gcd简介及应用实例及实例分析 #### GCD概述 GCD(Grand Central Dispatch),也称为块并发编程(BlockConcurrency Programming),是苹果公司在2009年WWDC上发布的一个多核编程模型。它通过简化多线程编程的方式...

    基于vue框架手写一个notify插件实现通知功能的方法

    - 在`$notify`方法中,创建了该组件的一个实例,并将通知内容传递给这个实例。 - 实例化后的组件挂载到了`document.body`中的一个新创建的`div`上,从而实现了通知的动态显示。 - **组件的挂载和销毁**: - 使用...

    Python库 | line_notify-0.1.4.tar.gz

    今天我们将深入探讨一个名为“line_notify”的Python库,通过分析“line_notify-0.1.4.tar.gz”这个压缩包文件,了解如何利用它来实现Line通知服务的集成。 Line Notify是Line官方推出的一款服务,允许用户通过API...

    Qt实例分析——QML属性绑定

    在本实例分析中,我们将深入探讨QML属性绑定的概念、语法以及如何结合C++动态发送信号到QML来实现更复杂的数据交互。 一、QML属性绑定概念 属性绑定是QML中的一种机制,它确保了当一个属性的值发生变化时,与其...

    Android观察者模式实例分析

    观察者模式(Observer Pattern)是一种行为设计模式,它允许你定义一个订阅机制,可以在对象状态改变时通知多个“观察”该对象的其他对象。在Android开发中,这种模式被广泛用于构建可扩展和灵活的系统,例如事件...

    Qt实例分析——QML创建新的Qt Quick类型

    本实例分析将探讨如何在Qt Quick环境中创建新的Qt Quick类型,以便更好地结合C++和QML的优点。 首先,我们需要了解QML类型的基本结构。QML类型通常由QML文件定义,它们描述了组件的属性、信号、方法以及可能的子...

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

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

    Python库 | cdk_events_notify-1.0.10-py3-none-any.whl

    例如,当一个新的S3对象上传到特定的存储桶时,你可以使用该库设置一个规则,自动触发一个Lambda函数进行文件处理或分析。此外,当云资源出现异常时,cdk_events_notify可以帮助发送警报通知,确保问题能够及时得到...

    process notify big data

    在IT行业中,"Process Notify Big Data" 可能是指一种针对大规模数据处理的系统或工具,其中涉及到32位架构的进程管理和数据通知机制。在这个主题下,我们可以深入探讨几个关键知识点: 1. **大数据处理**:大数据...

    Java线程等待用法实例分析

    "Java线程等待用法实例分析" Java线程等待用法实例分析是Java多线程编程中的一种重要机制,用于控制线程之间的同步和通信。通过使用wait()、notify()和notifyAll()方法,可以实现线程之间的协调和同步,从而避免...

    250个Java实例源代码

    Java是一种广泛使用的面向对象的编程语言,以其跨平台、高...每个实例都是一次动手实践的机会,有助于巩固理论知识,提高编程能力。在学习过程中,建议结合具体实例逐步分析、调试和优化代码,以达到最佳的学习效果。

    JAVA经典的40个实例

    每个实例都是一个独立的学习点,通过解决实际问题,你能更深刻地理解JAVA的特性和应用。"JAVA经典的40个实例"提供了一个绝佳的平台,让你在实践中学习和成长。记得在学习过程中不断思考、总结,将理论知识转化为实际...

    Ext.Notify:https 的 ExtJS 版本

    通过以上分析,我们可以了解到这个组件是一个基于 ExtJS 的通知系统,它强调安全性、灵活性和无依赖性,适用于构建复杂且注重用户体验的 Web 应用程序。开发者可以利用这个组件轻松地在应用中添加通知功能,同时保证...

    基于PHP实现的事件机制实例分析

    基于PHP实现的事件机制实例分析主要介绍了在PHP中如何自行实现一个事件机制。事件机制在编程中是一个非常重要的概念,特别是在面向对象编程中。事件可以看作是一种观察者模式(Observer Pattern),它允许对象之间...

    java中object类实例分析

    java中object类实例分析 Object类是Java语言中所有类的父类,位于java.lang包中。它是所有Java类的终极父类,数组也继承了Object类。然而,接口是不继承Object类的,Object类不作为接口的父类。 Object类提供了几...

    eclipse项目java线程实例

    wait()和notify()方法用于线程间的通信,一个线程可以通过wait()暂停执行,等待其他线程释放资源,而notify()或notifyAll()可以唤醒等待的线程。 此外,我们还可以利用Java的并发工具类,如ExecutorService和...

    一个JAVA多线程实例

    一个类可以实现多个接口,所以如果你的类已经继承了某个类,你仍然可以通过实现Runnable接口来创建线程。以下是一个简单的示例: ```java public class MyRunnable implements Runnable { @Override public void ...

    java中一个关于多线程的实例

    这个实例“多线程1”很可能是一个演示如何在Java中实现多线程的代码示例,特别是与“时钟”相关的应用。时钟是一个很好的多线程实践案例,因为它通常需要在后台持续运行并定期更新显示时间,这需要两个或多个线程...

Global site tag (gtag.js) - Google Analytics