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时,均无法重新启动线程,所以应该设置一定的时间让线程自行检测。