通常,多线程之间需要协调工作,例如两个人公用一个卫生间(每次只能一个人用),一个人必须等待另一个人用完,得知没有人使用的时候才能使用卫生间。
以上逻辑简单说就是:如果条件不满足,则等待。当条件满足时,等待该条件的线程将被唤醒。在java中,这个机制的实现依赖于wait() 和notify()。等待机制与锁机制密切关联的。例如
当线程A获得了obj锁后,发现条件condition不满足,就无法下一处理,于是线程A就等待(调用wait()方法)。
在另外一线程B中,如果B更改了某些条件,使得线程A的condition条件满足了,就可以唤醒线程A:
如果以使用卫生间作为示例,假设他们都要刷牙和洗脸。他们是这样约定的:轮流用,第一个人现刷牙,然后第二人刷牙;第一个人洗脸,然后第二个人洗脸。程序代码如下所示:
运行该示例,结果如下
[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]
以上逻辑简单说就是:如果条件不满足,则等待。当条件满足时,等待该条件的线程将被唤醒。在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]