一、notify()

作用:唤醒一个正在等待该线程的锁的线程

PS : 唤醒的线程不会立即执行,它会与其他线程一起,争夺资源

/**
 * Object类的notify()和notifyAll()方法详解
 */
public class MyNotify {

    // 在多线程间共享的对象上使用wait
    private String[] shareObj = {"true"};

    public static void main(String[] args) {
        MyNotify test = new MyNotify();
        //创建3个等待线程
        ThreadWait threadWait1 = test.new ThreadWait("线程1");
        ThreadWait threadWait2 = test.new ThreadWait("线程2");
        ThreadWait threadWait3 = test.new ThreadWait("线程3");
        //创建一个解放线程对象,用于通知等待线程运行
        ThreadNotify threadNotify = test.new ThreadNotify("释放线程");

        //等待线程启动,在释放线程把锁释放之后,争夺运行的机会
        threadWait1.start();
        threadWait2.start();
        threadWait3.start();

        //释放线程启动,sleep3秒后释放线程
        threadNotify.start();
    }

    /**
     * 线程等待类
     */
    class ThreadWait extends Thread {

        //调用父类构造方法设置线程名称
        public ThreadWait(String name) {
            super(name);
        }

        public void run() {
            synchronized (shareObj) {
                while ("true".equals(shareObj[0])) {
                    System.out.println("线程" + this.getName() + "开始等待");
                    long startTime = System.currentTimeMillis();
                    try {
                        shareObj.wait();//无尽等待,直至notify()或者notifyAll()
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    long endTime = System.currentTimeMillis();
                    System.out.println("线程" + this.getName()
                            + "等待时间为:" + (endTime - startTime));
                }
            }
            System.out.println("线程" + getName() + "等待结束");
        }
    }

    /**
     * 线程释放类
     */
    class ThreadNotify extends Thread {

        //调用父类构造方法设置线程名称
        public ThreadNotify(String name) {
            super(name);
        }

        public void run() {
            try {
                // 给等待线程等待时间
                sleep(3000);//此时sleep方法会获取对象锁,其他线程处于等待并获取锁的状态
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (shareObj) {
                System.out.println(this.getName() + "开始准备通知");
                shareObj[0] = "false";
                shareObj.notify();//解放一个正在等待的线程(随机)
//                shareObj.notifyAll();//解放所有等待的线程
                System.out.println(this.getName() + "通知结束");
            }
            System.out.println(this.getName() + "运行结束");
        }
    }
}

详见这里~

二、notifyAll()

作用:唤醒所有正在等待该线程的锁的线程

PS:并不一定会按线程优先级来执行

三、wait()

作用:导致当前的线程进入无尽等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法

四、wait(long timeout)

作用:导致当前的线程等待,直到其他线程调用此对象的notify() 方法或 notifyAll() 方法,或者指定的时间过完。

五、wait(long timeout, int nanos)

作用:类似于wait(long timeout)方法,更精准,附加时间在毫微秒范围0-999999。

六、常见异常

  • IllegalArgumentException -- 如果超时的值是负的或毫微秒的值不在0-999999范围内。
  • IllegalMonitorStateException -- 如果当前线程不是对象监视器的拥有者。
  • InterruptedException -- 如果另一个线程中断了当前线程。当这种异常被抛出当前线程的中断状态被清除。
12-20 16:13