zoukankan      html  css  js  c++  java
  • Java多线程编程——wait()和notify()、notifyAll()

    1、源码

    wait() notify() notifyAll()都是Object类中方法。源码如下所示:

        public final native void notify();
        public final native void notifyAll();
        public final native void wait(long timeout) throws InterruptedException;
        public final void wait() throws InterruptedException {
            wait(0);
        }

    可以看到它们都是final native修饰的方法。

    2、使用条件

    首先我们需要明确的一点是wait() notify() notifyAll()都是需要在线程拥有对象锁的情况下使用

    在没有对象锁的情况下使用会抛出异常。执行下面代码,会抛出 java.lang.IllegalMonitorStateException 异常

    package com.test;
    
    public class Test {
        public static void main(String[] args){
            try {
                Object obj = new Object();
                obj.wait();
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
    }

    3、作用

    3.1 wait()方法的作用

    wait()方法能够使当前线程停止,进入阻塞序列,等待被唤醒。

    wait()方法被调用后,当前线程会立即释放持有的对象锁。其他线程可以通过竞争的方式获取该对象锁。

    唤醒处于阻塞状态的线程,需要其他线程使用notify()或者notifyAll()方法。

    3.2 notify()方法的作用

    notify()方法能够唤醒处于阻塞状态(处于阻塞队列中)的线程。

    需要注意的是调用一次notify()方法只能唤醒一个处于阻塞状态的线程。

    而且调用notify()方法后,当前线程不会马上释放锁,被notify 的线程也不会马上获取该对象锁,而是需要等待当前线程执行完同步代码块。

    3.3 notifyAll()方法的作用

    notifyAll()方法能够唤醒正在等待同意共享资源的所有线程。

    4、实例

    直接上代码咯。

    package com.test;
    
    public class Test3 {
        
        class WaitThread implements Runnable{
    
            private Object lock;
            
            public WaitThread(Object lock) {
                // TODO Auto-generated constructor stub
                super();
                this.lock = lock;
            }
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    synchronized (lock) {
                        System.out.println(Thread.currentThread().getName() + 
                                " 即将进入阻塞状态  wait time = " + System.currentTimeMillis());
                        lock.wait();
                        System.out.println(Thread.currentThread().getName() + 
                                " 结束阻塞状态  wait time = " + System.currentTimeMillis());
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
            }
        }
        
        class NotifyThread implements Runnable{
    
            private Object lock;
            
            public NotifyThread(Object lock) {
                // TODO Auto-generated constructor stub
                super();
                this.lock = lock;
            }
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    synchronized (lock) {
                        System.out.println(Thread.currentThread().getName() + 
                                " 即将唤醒  notify time = " + System.currentTimeMillis());
                        lock.notify();
                        System.out.println(Thread.currentThread().getName() + 
                                " 唤醒线程执行结束  notify time = " + System.currentTimeMillis());
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
            }
        }
        
        public static void main(String[] args){
            try {
                Object lock = new Object();
                Test3 test3 = new Test3();
                Thread waitThread = new Thread(test3.new WaitThread(lock));
                waitThread.start();
                Thread.sleep(3000);
                Thread notifyThread = new Thread(test3.new NotifyThread(lock));
                notifyThread.start();
            } catch (Exception e) {
                // TODO: handle exception
            }            
        }
    }

    5、总结

    1 wait() notify() notifyAll() 方法只能在线程拥有对象锁的时候调用

    2 wait()方法调用后 当前线程会立即释放锁

    3 notify() notifyAll()方法执行后 当前对象并不会立即释放锁,而是要等同步代码块执行完成后才能释放锁

    4 notify()方法每次调用后只能唤醒处于阻塞队列中的一个线程,如果需要唤醒等待当前资源的所有线程需要使用notifyAll()方法

  • 相关阅读:
    C#开发模式——单例模式
    C#开发模式——单例模式
    Memcached的基础梳理
    Memcached的基础梳理
    Memcached的基础梳理
    Memcached的基础梳理
    13条只有程序员才能懂的内涵段子
    13条只有程序员才能懂的内涵段子
    网页性能优化
    webpack中使用ECharts
  • 原文地址:https://www.cnblogs.com/cuglkb/p/7275381.html
Copyright © 2011-2022 走看看