`

举例讲解线程的wait()和notify()

阅读更多
通常,多线程之间需要协调工作,例如两个人公用一个卫生间(每次只能一个人用),一个人必须等待另一个人用完,得知没有人使用的时候才能使用卫生间。
以上逻辑简单说就是:如果条件不满足,则等待。当条件满足时,等待该条件的线程将被唤醒。在java中,这个机制的实现依赖于wait() 和notify()。等待机制与锁机制密切关联的。例如
synchronized(obj){
while(!condition){
obj.wait();
}
}

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

如果以使用卫生间作为示例,假设他们都要刷牙和洗脸。他们是这样约定的:轮流用,第一个人现刷牙,然后第二人刷牙;第一个人洗脸,然后第二个人洗脸。程序代码如下所示:
package tarena;

public class Syn {

	public static void main(String[] args) {
		TwoPeople.ONE.start();
		TwoPeople.TWO.start();
	}
}

class TwoPeople extends Thread {

	private int i = 0;
	static Thread ONE = new TwoPeople(1);
	static Thread TWO = new TwoPeople(2);
	static Object lock = new Object();

	private TwoPeople(int i) {
		this.i = i;
	}

	public void run() {
		synchronized (lock) {
			try {
				if (i == 1) {
					this.brush();//1  people one brush
					lock.wait();//2  释放当前对象,进入等待状态
					this.release();//6 线程1 获取当前锁对象,并开始 people one release
					lock.notify();//7 注意:对象锁只能单一操作不能将该对象锁锁住,
																//所以这里只需要唤醒 线程2,进入就绪状态
					
				} else {
					this.brush();//3 线程2 people two brush
					lock.notify();//4  唤醒 线程1 并进入就绪状态
					lock.wait();//5  释放当前锁对象,让出CPU资源,使线程1 获取锁对象
					this.release();//8 获取对象锁,进入执行状态,最后run()结束
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	private void brush() {
		System.out.println("People  " + i + "  is brushing!");
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("People  " + i + "  is brushed!");
	}

	private void release() {
		System.out.println("People  " + i + "  is releasing!");
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("People  " + i + "  is released!");
	}
}


运行该示例,结果如下
引用

People  1  is brushing!
People  1  is brushed!
People  2  is brushing!
People  2  is brushed!
People  1  is releasing!
People  1  is released!
People  2  is releasing!
People  2  is released!
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    java 多线程同步方法的实例

    Java提供了多种机制来实现线程同步,主要包括synchronized关键字、wait()、notify()和notifyAll()方法以及ReentrantLock等。 1. **synchronized关键字**:这是Java中最基本的线程同步方式。它可以用于修饰方法或...

    Java线程中sleep和wait的区别详细介绍

    Java线程中的`sleep()`和`wait()`方法都是在多线程环境中...而`wait()`通常与`notify()`和`notifyAll()`结合使用,用于线程间的通信和协作,确保线程间的正确同步。了解这些概念有助于编写更健壮、高效的多线程应用。

    举例讲解Java中的多线程编程

    wait()和notify()方法则用于线程间通信,一个线程调用wait()会让出CPU,直到其他线程调用notify()唤醒它。 此外,Java还提供了ExecutorService和Future接口,以及ThreadPoolExecutor等类,用于更高级的线程池管理。...

    Java多线程-线程间的通信

    3. **等待和唤醒**:为了让两个线程能够交替打印数字,需要利用`wait()`和`notify()`方法。 **示例代码**: ```java public class PrintNumber implements Runnable { private final Object lock = new Object();...

    多线程精心总结

    - `wait()`、`notify()`和`notifyAll()`:这些方法用于线程间的协作,它们必须在`synchronized`块中使用。`wait()`使得当前线程进入等待状态,释放对象锁,直到其他线程调用`notify()`或`notifyAll()`唤醒它。`...

    第7章 多线程程序设计

    Java提供synchronized关键字实现互斥访问,以及wait()、notify()和notifyAll()方法来协调线程间的交互。 - synchronized:用于方法或代码块,确保同一时刻只有一个线程可以执行特定代码。 - volatile:确保线程可见...

    线程编程面试题

    - **`wait()`**:`wait()`是`Object`类的方法,用于释放当前对象的锁,并使当前线程进入等待状态,直到被`notify()`或`notifyAll()`唤醒。 #### 62、同步和异步有何异同,在什么情况下分别使用它们?举例说明。 - ...

    Java多线程文章系列.pdf

    - `wait()`, `notify()`, `notifyAll()`用于线程间的同步。 - `suspend()`, `resume()`, `sleep()`用于线程控制。 - **讨论**: - `suspend()`和`resume()`已废弃,推荐使用更安全的同步机制。 #### 五、Java多...

    多线程面试59题.pdf

    - **wait/notify**:利用synchronized关键字和Object类中的wait/notify方法实现线程间的等待与唤醒。 #### 九、获取线程的返回结果 - **Callable接口**:与Runnable接口类似,但Callable接口的方法可以返回结果,...

    java中的 双线程,举一反三

    6. **线程通信**:线程间通信(IPC)用于协调不同线程的工作,如通过wait()、notify()和notifyAll()方法实现线程间的协作。在提供的类中,Producer和Customer可能通过这种方式交换关于商品存储(Store)的信息。 7....

    达内java的控制台的Thread的举例

    2. **条件变量**:如`wait()`、`notify()`和`notifyAll()`方法,它们是`Object`类的方法。生产者和消费者可以使用这些方法来在特定条件下挂起或唤醒线程。 3. **阻塞队列**:如`BlockingQueue`接口及其实现类,如`...

    析Java多线程机制.pdf

    Java提供了一些机制来实现线程之间的通信和协作,如使用wait()和notify()方法、使用join()方法等。 Java多线程机制是Java语言中的一种重要机制,能够提高程序的执行效率。但是,多线程机制的实现需要考虑线程之间的...

    JAVA实验典型举例

    理解线程的同步和通信机制,如synchronized关键字和wait/notify机制,是提升程序性能的关键。 此外,IO流和NIO(New IO)在文件操作和网络通信中扮演着重要角色。例子可能包含读写文件,或者通过Socket进行客户端-...

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

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

    浅析Java中如何实现线程之间通信

    在`demo3`的示例中,我们可以通过调用对象的`wait()`方法使线程进入等待状态,而`notify()`或`notifyAll()`则唤醒等待的线程。这些方法需要在同步块或同步方法中调用,以防止其他线程在不适当的时候改变线程的状态。...

    Java高级工程师面试宝典

    Condition 的功能类似于在传统的线程技巧中使用 wait() 和 notify() 方法来实现线程之间的通信和同步。Condition 可以 êtreseen 作为一种高级的锁,它具有等待、通知和超时等机制,可以用来实现复杂的同步机制。

    java thread

    04_举例.avi 文件可能包含了一些实际示例,展示如何在Java代码中创建和管理线程,以及如何应用上述同步机制来解决实际问题。 通过这个学习教程,你将能够理解和掌握Java线程的基本操作,以及如何通过同步机制保证多...

    J2SE_5.0_第07章_容器1.rar

    5. **线程同步**:如何通过synchronized关键字、wait()、notify()和notifyAll()方法实现线程间的同步,防止数据竞争问题。 6. **死锁**:线程同步不当可能导致死锁,即两个或更多线程相互等待对方释放资源,形成僵局...

    并发编程面试专题.pdf

    3. wait和sleep方法的区别:wait方法是Object类中的一个方法,当线程调用wait方法时,它会释放对象的锁,然后进入等待状态,直到其他线程调用notify或notifyAll方法将其唤醒。而sleep方法是Thread类中的一个静态方法...

    Java简明教程-第3版-课件和程序举例源码

    8. **多线程**:如何创建和管理线程,同步机制如synchronized关键字和wait()、notify()方法。 9. **文件和目录操作**:Java的File类提供了操作文件和目录的方法,如创建、删除、重命名等。 10. **网络编程**:Socket...

Global site tag (gtag.js) - Google Analytics