`

concurrent: wai notify notifyAll

 
阅读更多

转载自:http://sishuok.com/forum/blogPost/list/3674.html

 

通常,多线程之间需要协调工作。例如,浏览器的一个显示图片的线程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中的一个才有机会获得锁继续执行

public class TestWaitNotify {
	// 锁
	Byte lock = 0;
	// 条件,当条件为真,AThread才能往下执行,否则会等待,直到有线程将条件改为真。
	Boolean condition = false;
    //内部类:等待线程 
	class AThread extends Thread {
		public void methodA() {
			if (condition) {
				System.out.println("方法methodA执行");
			} else {
				try {
					/*
					 * 这里要特别注意,
					 * (1)只能在同步控制方法或同步块中调用wait()、notify()和notifyAll()。如果在非同步的方法里调用这些方法,在运行时会抛出IllegalMonitorStateException异常。
					 * (2)synchronized的锁与notity的调用对象必须一致,否则也会抛出IllegalMonitorStateException异常;
					 * (3)下面的代码也会使抛出异常:
					 *      synchronized(condtion){condition=true;condition.wait();
					 *      因为condition改变以后,synchronized中的对象与调用wait方法的对象已经不同。
					 *      所以condtion与lock要分开,因为condtion会改变
					 * 
					 */
					synchronized (lock) {
						System.out.println("方法methodA等待");
						lock.wait();
						System.out.println("方法methodA等待结束");
					}
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		@Override
		public void run() {
			methodA();
		}
	}
   //内部类 notify线程
	class BThread extends Thread {
		@Override
		public void run() {
			synchronized (lock) {
				System.out.println("方法methodB执行");
				condition = true;
				lock.notifyAll();
				System.out.println("方法methodB唤醒");
			}
		}
	}

	public static void main(String[] args) {
		TestWaitNotify t = new TestWaitNotify();
		TestWaitNotify.AThread aThread = t.new AThread();
		aThread.start();
		TestWaitNotify.BThread bThread = t.new BThread();
		bThread.start();
	}
}

 

分享到:
评论

相关推荐

    backport-util-concurrent.jar

    backport-util-concurrent.jarbackport-util-concurrent.jarbackport-util-concurrent.jar

    atlassian-util-concurrent-0.0.12.jar.zip

    《深入解析Atlassian Util Concurrent库:0.0.12版本》 在IT行业中,高效且可靠的并发处理是系统性能优化的关键因素之一。Atlassian公司,以其强大的协作工具如Jira、Confluence等闻名,也提供了许多开源工具来支持...

    grunt-concurrent:同时运行grunt任务

    $ npm install --save-dev grunt-concurrent 用法 require ( 'load-grunt-tasks' ) ( grunt ) ; grunt . initConfig ( { concurrent : { target1 : [ 'coffee' , 'sass' ] , target2 : [ 'jshint' , 'mocha' ] ...

    mulle-concurrent::antenna_bars:一个无锁且无等待的哈希表(还有一个数组)

    《mulle-concurrent:构建无锁且无等待的哈希表与数组》 在软件开发中,尤其是在多线程环境中,数据结构的选择对于程序性能和并发性至关重要。`mulle-concurrent`是一个专注于并发编程的C语言库,其中的`:antenna_...

    concurrent-1.3.3.jar

    concurrent.jar 里面有,使用Apache JCS 时候需要的EDU/oswego/cs/dl/util/concurrent/Channel ,编译 jcaptcha时候需要第EDU.oswego.cs.dl.util.concurrent.ClockDaemon类, concurrent-1.3.3.jar

    Concurrent:用于展示竞争名单

    标题"Concurrent:用于展示竞争名单"可能是在指一个项目或示例,旨在演示如何在并发环境中处理竞争条件。竞争条件发生在多个线程同时访问和修改共享数据时,可能导致数据不一致。Java通过锁机制(如`synchronized`...

    concurrent:java并发编程的示例和原始代码分析

    本资源“concurrent:java并发编程的示例和原始代码分析”提供了深入理解和实践Java并发特性的宝贵材料。以下是对该资源中可能包含的知识点的详细说明: 1. **Java并发API**: 这个资源可能涵盖了Java的并发库,包括`...

    backport-util-concurrent-3.1.jar和geronimo-stax-api_1.0_spec-1.0.1.jar

    标题中的"backport-util-concurrent-3.1.jar"和"geronimo-stax-api_1.0_spec-1.0.1.jar"是两个Java库文件,它们在解决Eclipse Axis2 Codegen插件报错问题时起着关键作用。Axis2是一个流行的Web服务框架,而Codegen...

    concurrent:并行处理 Java 示例

    首先,Java中的`java.util.concurrent`包是进行并发编程的核心库,包含了线程池、并发集合、锁机制等关键组件。线程池如`ExecutorService`和`ThreadPoolExecutor`,通过复用线程来提高性能,避免频繁创建和销毁线程...

    java-concurrent:Java并发

    Java的`wait()`、`notify()`和`notifyAll()`方法用于线程间的通信,但它们必须在同步块或同步方法中使用,以防止死锁和其他并发问题。 9. **并发设计模式** 了解如生产者消费者模型、读者写者模式、双检锁/双重...

    Java多线程同步(wait()notify()notifyAll())[文].pdf

    本文将深入探讨Java中的wait()、notify()和notifyAll()方法,以及synchronized关键字和原子操作在多线程环境中的应用。 1. **wait()方法**: - wait()是Object类的一个方法,它的作用是让当前线程暂停执行并释放它...

    concurrent:Java并发,源可用于android和java进行并发

    本资源“concurrent:Java并发,源可用于android和java进行并发”提供了用于Android和Java平台的并发编程的相关源码,这对于我们深入理解和实践并发编程具有很高的价值。 首先,我们要理解Java中的并发基础。Java...

    ao-concurrent:并发编程实用程序

    - **wait()** 和 **notify()**:基于对象监视器的线程通信方式,用于线程间的协作。 - **Phaser**:一种灵活的线程同步机制,可进行多阶段的同步。 6. **并发设计模式** - **生产者-消费者模式**:通过队列进行...

    tascalate-concurrent:阻塞(IO绑定)的实现可取消java.util.concurrent.CompletionStage和java.util.concurrent.ExecutorService-s的相关扩展

    在版本,工件已重命名:新名称: < dependency> < groupId>net.tascalate</ groupId> < artifactId>net.tascalate.concurrent</ artifactId> < version>0.9.5</ version> <!-- Any version above 0.8.0, the ...

    JDK-Concurrent:深入学习JDK Concurrent包,以及其他线程相关源码;

    开始从原始二进制研究Concurrent包,以及其他并发相关的包,对于途中遇到的不明白的东西,也会作相应了解。 该项目的缘由是看CopyOnWriteArrayList二进制时,对Unsafe类一无所知,才有了好钻钻一番的冲动。 ...

    java-concurrent:java 并发编程例子

    `java-concurrent`通常指的是Java的并发包`java.util.concurrent`,这个包提供了大量的类和接口,帮助开发者有效地管理和控制并发操作。下面我们将深入探讨这个主题。 首先,`java.util.concurrent`包中的核心组件...

    manuel-contrib-concurrent:轻松同时运行手动任务

    安装将此存储$HOME/.manuel.d/plugins到您的 manuel 插件目录(默认$HOME/.manuel.d/plugins ): $ cd ~ /.manuel.d/plugins$ git clone git://github.com/ShaneKilkelly/manuel-contrib-concurrent.git用法只需将...

    java7源码-Java-concurrent:Java并发编程

    io.github.hank.java.concurrent.n2 - 同步与异步 io.github.hank.java.concurrent.n3 - Java线程 io.github.hank.java.concurrent.n4 - 共享模型之管程 io.github.hank.java.concurrent.n5 - 共享模型之内存 io....

    javaconcurrent源码-java_concurrent:javaconcurrent包源代码学习,及相关实践示例

    Java `concurrent` 包是Java提供的一个核心库,它为并发编程提供了丰富的工具和类,帮助开发者编写更加高效和线程安全的代码。本资源——`java_concurrent` 源码,提供了对Java并发包的深入学习材料以及实践示例,...

    imgr-concurrent:imgr 的测试用例

    在这个名为"imgr-concurrent"的项目中,我们看到的是一个与图像处理相关的JavaScript库的测试用例,特别是针对并发操作的。 "imgr"可能是一个JavaScript库,专门设计用于高效地处理图像,比如缩放、裁剪、转换格式...

Global site tag (gtag.js) - Google Analytics