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

本文通过一个具体的例子,介绍了Java中多线程如何使用wait和notify方法来实现线程间的同步与唤醒机制。文章详细展示了如何利用synchronized关键字确保线程安全,并通过两个线程模拟轮流使用卫生间的场景。
通常,多线程之间需要协调工作,例如两个人公用一个卫生间(每次只能一个人用),一个人必须等待另一个人用完,得知没有人使用的时候才能使用卫生间。
以上逻辑简单说就是:如果条件不满足,则等待。当条件满足时,等待该条件的线程将被唤醒。在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!");
}
}


运行该示例,结果如下
[quote]
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!
[/quote]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值