Java多线程_wait/notify/notifyAll方法

Posted 橘子洲头。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程_wait/notify/notifyAll方法相关的知识,希望对你有一定的参考价值。

关于这三个方法,我们可以查询API得到下列解释:

wait():导致当前的线程等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法或者指定的事件用完

notify():唤醒在此对象监视器上等待的单个线程

notifyAll():唤醒在此对象监视器上等待的所有线程

我们需要注意的点
(1)wait()、notify/notifyAll() 方法是Object的本地final方法,无法被重写。

(2)wait() 与 notify/notifyAll 方法必须在同步代码块中使用。

(3)由于 wait() 与 notify/notifyAll() 是放在同步代码块中的,因此线程在执行它们时,肯定是进入了临界区中的,即该线程肯定是获得了锁的。


(4)当线程执行wait()时,会把当前的锁释放,然后让出CPU,进入等待状态。

(5)当执行notify/notifyAll方法时,会唤醒一个处于等待该 对象锁 的线程,然后继续往下 执行,直到执行完退出对象锁锁住的区域(synchronized修饰的代码块)后再释放锁。

(6)如果在执行wait() 与 notify/notifyAll() 之前没有获得相应的对象锁,就会抛出:java.lang.IllegalMonitorStateException异常。

下面我们看代码:

 

public class WaitNotifyDemo {
    public static void main(String[] args) {
        Object lock = new Object();

        WaitMathodThread w = new WaitMathodThread(lock);
        w.start();

        NotifyMethodThread n = new NotifyMethodThread(lock);
        n.start();
    }

    public void waitMethod(Object lock) {
        try {
            synchronized (lock) {
                System.out.println("begin wait() ThreadName=" + Thread.currentThread().getName());
                lock.wait();
                System.out.println("  end wait() ThreadName=" + Thread.currentThread().getName());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void notifyMethod(Object lock) {
        try {
            synchronized (lock) {
                System.out.println("begin notify() ThreadName=" + Thread.currentThread().getName() + " time="
                        + System.currentTimeMillis());
                lock.notify();
                Thread.sleep(5000);
                System.out.println("  end notify() ThreadName=" + Thread.currentThread().getName() + " time="
                        + System.currentTimeMillis());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class WaitMathodThread extends Thread {
    private Object lock;

    public WaitMathodThread(Object lock) {
        super();
        this.lock = lock;
    }

    @Override
    public void run() {
        WaitNotifyDemo wnd = new WaitNotifyDemo();
        wnd.waitMethod(lock);
    }
}

class NotifyMethodThread extends Thread {
    private Object lock;

    public NotifyMethodThread(Object lock) {
        super();
        this.lock = lock;
    }

    @Override
    public void run() {
        WaitNotifyDemo wnd = new WaitNotifyDemo();
        wnd.notifyMethod(lock);
    }
}

 

运行结果:

从这个测试中可以看出调用了wait()方法后会立即释放锁,线程进入等待状态,而调用了notify()方法后并不会立即释放锁,会等到走完synchronized修饰的临界区时,才会释放锁。
所以一般在调用了notify()方法后最好马上退出synchronized修饰的临界区。

 

以上是关于Java多线程_wait/notify/notifyAll方法的主要内容,如果未能解决你的问题,请参考以下文章

java_第9章:多线程

Java之旅_高级教程_多线程编程

Java_多线程

Java千百问_02基本使用(012)_如何编写多线程Socket程序

Java基础__Java中多线程那些事

黑马程序员_java08_多线程