java中wait()、notify()以及notifyAll()的使用

首先我们先来了解一下java线程的状态转换图:
java中wait()、notify()以及notifyAll()的使用_第1张图片
从图上可以看出,当调用wait()方法之后,线程便进入了等待状态,直到调用了notify()/notifyAll()方法之后,则唤醒线程去竞争对象锁

  • wait()方法

    wait()方法是Object类中的方法,源码中是这样写的:

 public final native void wait(long timeout) throws InterruptedException;
 public final void wait(long timeout, int nanos) throws InterruptedException {
        if (timeout < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
            timeout++;
        }

        wait(timeout);
 }
 public final void wait() throws InterruptedException {
        wait(0);
 }    

该方法用来使得当前线程进入等待状态,直到接到通知或者被中断打断为止。在调用wait()方法之前,线程必须要获得该对象的对象级锁;换句话说就是该方法只能在同步方法或者同步块中调用,如果没有持有合适的锁的话,线程将会抛出异常IllegalArgumentException。调用wait()方法之后,当前线程则释放锁。

  • notify()方法
    源码中的定义:
    public final native void notify();
    该方法用来唤醒处于等待状态获取对象锁的其他线程。如果有多个线程则线程规划器任意选出一个线程进行唤醒,使其去竞争获取对象锁,但线程并不会马上就释放该对象锁,wait()所在的线程也不能马上获取该对象锁,要程序退出同步块或者同步方法之后,当前线程才会释放锁,wait()所在的线程才可以获取该对象锁。
  • notifyAll()方法
    源码中的定义:
    public final native void notifyAll();
    notifyAll()方法和notify()方法的工作方式相同,但是notifyAll()与notify()方法的区别在于notifyAll()方法使所有原来在该对象上处于等待状态的线程全部被唤醒,当程序从synchronized同步块或者同步方法中退出时,所有被唤醒准备竞争对象锁的线程便会去竞争该对象的对象级别锁,然后获取到对象锁的线程继续执行,当他退出synchronized同步块或者同步方法,释放锁后,其他被唤醒的线程继续竞争,直到所有被唤醒的线程都执行完。
    总结
    线程调用了对象的wait()方法后,线程便处于该对象的等待池中,等待池中的线程不会去竞争该对象的对象锁;直到线程调用了notify()方法(任意唤醒等待池中的一个线程)/notifyAll()方法(唤醒等待池中的所有线程),被唤醒的线程则会进入该对象的锁池中去竞争该对象锁;被唤醒的线程如果没有竞争到该对象的对象锁,则他继续留在锁池中,除非线程再次调用wait()方法,则线程才会重新回到等待池中。

你可能感兴趣的:(java-并发编程)