`

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

 

分享到:
评论

相关推荐

    java之wait,notify的用法([ 详解+实例 ])

    wait方法可以让当前线程暂时放弃对象锁,让其他线程使用,而sleep和suspend方法不能做到这一点。 结论 在Java多线程编程中,wait和notify是两个非常重要的方法,它们用于线程之间的通信和同步。wait方法用于让当前...

    Java 同步锁 wait notify 学习心得

    `notify()`方法随机唤醒正在等待该对象锁的线程之一。被唤醒的线程将有机会重新获取锁并继续执行。然而,`notify()`并不保证被唤醒的线程会立即执行,因为线程调度取决于操作系统的线程调度策略。 #### `notifyAll...

    等待机制与锁机制wait notify

    需要注意的是,`wait()`、`notify()`和`notifyAll()`的调用者应当是持有对象锁的线程,否则会出现异常。此外,为了防止死锁和饥饿现象,合理地设计同步策略和唤醒逻辑至关重要。 总结来说,`wait`、`notify`和`...

    wait_notify_demo

    在Java中,`wait()`、`notify()`和`notifyAll()`方法都是与对象锁相关的,它们用于控制线程的同步。使用这些方法的前提是线程必须拥有对象的监视器,也就是对象锁。这是通过在synchronized块或方法中调用它们来实现...

    Java 同步方式 wait和notify/notifyall

    1. **wait()**:这个方法会让当前持有对象锁的线程进入等待状态,释放对象锁,让其他线程有机会获取锁。等待的线程必须在某个对象的监视器上等待,即在线程进入同步代码块或同步方法之前调用`wait()`。线程只有被...

    Java多线程wait和notify

    `wait()` 方法会让当前持有锁的线程进入等待状态,释放锁,直到其他线程调用 `notify()` 或 `notifyAll()` 唤醒它。`notify()` 则会随机选择一个等待在该对象监视器上的线程并唤醒它,而 `notifyAll()` 则会唤醒所有...

    深入理解Wait、Notify和Wait与sleep区别

    3. **notifyAll()**:与`notify()`类似,但它会唤醒所有等待该对象的线程,这些线程都会尝试获取对象锁,最终只有一个成功并继续执行,其他线程仍然会在锁池中等待。 现在我们来看`sleep()`方法,它来自Thread类,...

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

    当一个线程调用`notify()`时,会随机选择一个正在等待该对象锁的线程使其恢复运行。 - **`notify();`**:在`ThreadB`的`synchronized`代码块内,当累加操作完成后,调用`notify()`唤醒等待中的`ThreadA`线程,使得...

    java中几个notify、wait使用实例

    当一个线程执行到`wait()`方法时,它会释放当前持有的锁并进入等待状态,直到其他线程调用同一锁上的`notify()`或`notifyAll()`方法唤醒。`wait()`方法还有两个重载版本:`wait(long timeout)`和`wait(long timeout,...

    Java多线程中wait、notify、notifyAll使用详解

    wait()方法是使当前线程自动释放占有的对象锁,并等待notify。该方法的调用必须在synchronized代码块或者方法中,因为wait()方法需要当前线程必须获得对象锁。在wait()方法执行时,当前线程会释放当前的锁,然后让出...

    Java的sychronized、wait和notify范例

    在实际开发中,`wait()`、`notify()`和`synchronized`常常用于实现生产者消费者模型、读写锁等高级并发场景。通过理解并熟练掌握这些概念,开发者可以编写出更加高效、可靠的多线程程序。 在提供的压缩包文件`java_...

    主线程去控制子线程wait与notify

    首先,`wait()`方法会导致当前线程进入等待状态,直到其他线程调用同一个对象的`notify()`或`notifyAll()`方法唤醒它。而`notify()`方法则会唤醒一个正在该对象上等待的线程,如果有多个线程在等待,哪个线程被唤醒...

    浅谈java多线程wait,notify

    在Java中,wait机制用于暂停当前线程的执行,并释放当前对象的锁,以便让其他线程获得锁并执行。在使用wait机制时,需要注意以下几点: * wait方法必须在synchronized块中调用,以确保线程安全。 * wait方法会释放...

    wait,notify等线程知识.pdf

    与notify()类似,notifyAll()会唤醒所有等待该对象锁的线程。然而,这些线程仍然需要在获得锁后才能继续执行,这意味着只有一个线程能够在其他线程之前获取到锁并继续运行。 4. **Lock接口**: 为了解决`...

    java-wait和notify的用法.pdf

    `wait()`方法的作用是使当前持有对象锁的线程暂停执行,进入等待池,释放对象锁,直到其他线程调用同一对象的`notify()`或`notifyAll()`方法来唤醒它。当线程被唤醒后,它并不会立即恢复执行,而是需要再次竞争对象...

    Object类wait及notify方法原理实例解析

    wait方法的调用必须在synchronized块中进行,因为wait方法需要释放当前对象占有的锁。 notify方法: notify方法也是Object类中的一个方法,它用于唤醒当前对象上等待的线程。notify方法不会释放锁,因此在使用...

    详解Java程序并发的Wait-Notify机制

    只有持有对象锁的线程才能调用`wait()`, `notify()`, `notifyAll()`。 **使用Wait-Notify机制时需要注意的事项:** 1. `wait()`, `notify()`, `notifyAll()`必须在`synchronized`代码块或方法中调用,以确保线程...

    Java 中Object的wait() notify() notifyAll()方法使用

    很多人会疑惑为什么必须持有这个对象的锁才能调用对象的wait()和notify()方法呢?其实这是因为wait()和notify()方法需要在synchronized块中使用,以确保线程安全。 在使用wait()和notify()方法时,需要注意以下几点...

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

    - notify()方法会唤醒一个正在等待该对象锁的线程,但不保证是哪个线程,且唤醒的线程需要获取到锁才能继续执行。 - notifyAll()则会唤醒所有等待该对象锁的线程,这些线程都将进入锁的竞争队列。 3. **...

Global site tag (gtag.js) - Google Analytics