wait和notify是通过对对象进行锁,来实现同步和互斥。
wait和notify函数需要在一段的同步代码中,即在 synchronized的代码段中。
简单的示例代码。
static class TestThread {
public Boolean locked = false;
public void run() {
long last = System.currentTimeMillis();
synchronized (locked) {
while (locked) {
// 释放这个锁吗?
try {
System.out.println(Thread.currentThread().toString()
+ " now is waiting");
// 也就是最后测试的结果是,这个wait处如果没有写具体时间的话,其他的notify是不会叫醒这里的锁的。
locked.wait(1000);
System.out.println(Thread.currentThread().toString()
+ " waiting is end");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// System.out.println(Thread.currentThread().toString()
// + " lock locked ");
locked = true;
// work。
// System.out.println(Thread.currentThread().toString()
// + " work start ");
// System.out.println(Thread.currentThread().toString()
// + " work start locked" + locked);
long now = System.currentTimeMillis();
while (now - last < 1000) {
locked = true;
now = System.currentTimeMillis();
}
locked = false;
// System.out.println(Thread.currentThread().toString()
// + " work end notify" );
synchronized (locked) {
locked.notifyAll();
System.out.println(Thread.currentThread().toString()
+ " work end notify");
}
// System.out.println(Thread.currentThread().toString()
// + " work finished ");
}
}
/**
* @param args
*/
public static void main(String[] args) {
final TestThread tt = new TestThread();
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
public void run() {
tt.run();
}
}).start();
}
输出结果为:
Thread[Thread-2,5,main] now is waiting
Thread[Thread-3,5,main] now is waiting
Thread[Thread-4,5,main] now is waiting
Thread[Thread-1,5,main] work end notify
Thread[Thread-0,5,main] work end notify
Thread[Thread-2,5,main] waiting is end
Thread[Thread-2,5,main] work end notify
Thread[Thread-3,5,main] waiting is end
Thread[Thread-3,5,main] work end notify
Thread[Thread-4,5,main] waiting is end
Thread[Thread-4,5,main] work end notify
这里我锁的是TestThread中的Boolean 对象 locked。通过synchronized (locked) 将locked对象锁住,但是 locked.wait(1000)又将这个locked对象锁给释放了,导致其他线程可以访问locked对象。然后被释放的对象被其他线程使用结束后,使用 locked.notifyAll(); 通知其他等待该对象的线程当前对象可以使用。这里需要注意的地方,一般说明的是wait()的线程都会被提醒并获得对象锁再继续运行,但实际上我测试的结果不是这样的,如果我这里没有设置时间如这里的1000ms,则当使用notify或notifyAll时,均无法重新启动线程,所以应该设置一定的时间让线程自行检测。