* wait()、notify()和notifyAll()方法是本地方法,并且为final方法,无法被重写。 * 调用某个对象的wait()。让出对象所有权,休眠当前线程 * 调用某个对象的notify()方法能够唤醒一个正在等待这个对象的monitor的线程 * 如果有多个线程都在等待这个对象的monitor,则只能唤醒其中一个线程。 * 唤醒后并还不能执行,还必须等到获取对象所有权才能执行。 * 调用notifyAll()方法能够唤醒所有正在等待这个对象的monitor的线程。 * 唤醒后并还不能执行,还必须等到获取对象所有权才能执行。 * 要同步的代码块必须要使用synchronized包含起来,代码块执行完毕后才会释放对象所有权 // 上面尤其要注意一点,一个线程被唤醒不代表立即获取了对象的monitor(锁), // 只有等调用完notify()或者notifyAll()并退出synchronized块,释放对象锁后, // 其余线程才能获得锁,才可获得锁执行。 public class Test { public static Object object = new Object(); public static void main(String[] args) { Thread1 thread1 = new Thread1(object); Thread2 thread2 = new Thread2(object); Thread3 thread3 = new Thread3(object); thread2.start(); thread3.start(); try { Thread.sleep(200); } catch (InterruptedException e) {} thread1.start(); } } class Thread1 extends Thread{ private Object object; public Thread1(Object object){this.object = object;} @Override public void run() { synchronized (object) { // 获取对象锁,该代码块才有执行的机会,其他线程则无法执行被该对象锁住的代码块 // object.notify(); // Thread2,Thread3只有一个线程被唤醒,并获得锁(object对象),执行代码块,释放锁,另外一个线程永远没有机会被唤醒 object.notifyAll(); // Thread2,Thread3两个线程都被唤醒,但是每个时刻只有一个线程获得锁(object对象),执行完毕之后, // 另一个线程获得锁,执行代码块,释放锁 System.out.println("线程"+Thread.currentThread().getName()+"调用了object.notify()"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } // synchronized语句块执行完毕才释放锁 System.out.println("线程" + Thread.currentThread().getName() + "释放了锁"); } } class Thread2 extends Thread{ private Object object; public Thread2(Object object){this.object = object;} @Override public void run() { synchronized (object) { try { System.out.println("线程" + Thread.currentThread().getName() + "sleep"); object.wait(); // object.notify(); Thread.sleep(1000); } catch (InterruptedException e) { } System.out.println("线程"+Thread.currentThread().getName()+"获取到了锁"); } } } class Thread3 extends Thread{ private Object object; public Thread3(Object object){this.object = object;} @Override public void run() { synchronized (object) { try { System.out.println("线程" + Thread.currentThread().getName() + "sleep"); object.wait(); // object.notify(); Thread.sleep(1000); } catch (InterruptedException e) { } System.out.println("线程"+Thread.currentThread().getName()+"获取到了锁"); } } }