zoukankan      html  css  js  c++  java
  • 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修饰的临界区。

  • 相关阅读:
    浅谈.NET和JAVA的跨平台
    ADO.NET获取TIPTOP存储过程的返回值
    Hide DataGrid Columns via HeaderText
    笑话一则:开车的最高境界
    [推薦]面试时最常问的15问题
    美国小学生守则 VS 中国小学生守则
    Embedded UserControls: Revisited
    SOA认识存误区 详解SOA企业部署的六大关键要素
    Java、.NET,为什么不合二为一?
    [轉]informix语句祥解
  • 原文地址:https://www.cnblogs.com/ericz2j/p/10283484.html
Copyright © 2011-2022 走看看