美文网首页
等待通知机制之wait/notify

等待通知机制之wait/notify

作者: sunpy | 来源:发表于2018-11-01 17:23 被阅读11次

wait/notify

wait()方法的作用就是将当前执行代码的线程进行等待,wait()方法时Object类的方法用来将当前线程置入 “预执行队列” 中,在wait()方法所在的代码行处停止执行,直到收到通知或者中断为止。
notify()方法的作用就是将多个等待线程,由线程规划期随机挑选出其中一个wait状态的线程,发出notify唤醒。

  1. wait/notify方法调用前,需要先获取对象锁
public class Test {
    
    public static void main(String[] args) {
        try {
            Object obj = new Object();
            obj.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

结果:

[Console output redirected to file:D:\console.txt]
Exception in thread "main" java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:503)
    at cn.spy.thread.test.Test.main(Test.java:8)
  1. 等待唤醒例子
public class MyThread1 extends Thread {

    private Object lock;

    public MyThread1(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        try {
            synchronized (lock) {
                System.out.println(Thread.currentThread().getName() + " start wait " + System.currentTimeMillis());
                lock.wait();
                System.out.println(Thread.currentThread().getName() + " end wait " + System.currentTimeMillis());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class MyThread2 extends Thread {

    private Object lock;

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

    @Override
    public void run() {
        synchronized (lock) {
            System.out.println(Thread.currentThread().getName() + " start notify " + System.currentTimeMillis());
            lock.notify();
            System.out.println(Thread.currentThread().getName() + " end notify " + System.currentTimeMillis());
        }
    }
}

public class Test {
    
    public static void main(String[] args) {
        try {
            Object lock = new Object();
            MyThread1 mt1 = new MyThread1(lock);
            mt1.setName("MyThread1");
            mt1.start();
            Thread.sleep(5000);
            MyThread2 mt2 = new MyThread2(lock);
            mt2.setName("MyThread2");
            mt2.start();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

结果:

[Console output redirected to file:D:\console.txt]
MyThread1 start wait 1541050962125
MyThread2 start notify 1541050967127
MyThread2 end notify 1541050967127
MyThread1 end wait 1541050967127

说明:可以发现MyThread2在执行notify方法唤醒MyThread1,然后MyThread2没有马上释放线程,MyThread1没有马上获取线程。
① 等待通知的执行顺序是如果我们执行了notify();方法并不会马上就释放线程了,而那个wait状态的线程也不能马上获取该对象锁。得等到notify();方法的线程执行完(也就是退出了synchronized代码块后),线程才会释放锁,而呈wait(); 状态的线程才可以获取该对象锁。
② 当前如果有多个线程处于等待的状态,那么使用notify();方法,线程规划器只会随机的挑选出其中一个线程。
③ wait方法执行后,锁自动释放,但是执行完notify方法,锁不会自动释放。

总结

  1. wait/notify方法调用前,需要先获取对象锁
  2. notify唤醒多个等待线程,是随机挑选出的。
  3. wait方法执行后,锁自动释放,但是执行完notify方法,锁不会自动释放。
  4. notify唤醒的线程不会马上执行(因为notify方法的执行,锁不会自动释放)。
  5. 当线程呈wait();状态时,调用线程对象的interrupt();方法会报一个InterruptedException异常。

相关文章

网友评论

      本文标题:等待通知机制之wait/notify

      本文链接:https://www.haomeiwen.com/subject/zxbtxqtx.html