Java并发-10.等待/通知

2019-05-28 13:20:47 浏览数 (1)

等待/通知的方法定义在所有对象的超类java.lang.Object上。

方法

描述

notify()

通知一个在对象上等待的线程,使其从wait()方法返回,返回的前提是线程获取了对象的锁

notifyAll()

通知所有在该对象上等待的线程

wait()

调用该方法的线程进入WAITING状态,只有等待另外线程的通知或被中断才会返回,调用wait()方法会释放对象的锁

wait(long)

超时等待一段时间,毫秒为单位

wait(long, int)

对超时时间的细粒度控制

,可以达到纳秒

示例代码:

代码语言:javascript复制
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @author pengjunzhe
 */
public class WaitNotify {
    static boolean flag = true;
    static Object lock = new Object();

    public static void main(String[] args) throws Exception {
        Thread waitThread = new Thread(new Wait(), "WaitThread");
        waitThread.start();
        TimeUnit.SECONDS.sleep(1);
        Thread notifyThread = new Thread(new Notify(), "NotifyThread");
        notifyThread.start();
    }

    public static class Wait implements Runnable {
        @Override
        public void run() {
            // 加锁,获取lock对象的Monitor
            synchronized (lock) {
                // 条件不满足时,继续wait,同时释放lock的锁
                while (flag) {
                    try {
                        System.out.println(Thread.currentThread()   " flag is true. wait @ "
                                  new SimpleDateFormat("HH:mm:ss").format(new Date()));
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // 条件满足时,完成工作
                System.out.println(Thread.currentThread()   " flag is false. running @ "   new SimpleDateFormat("HH:mm:ss").format(new Date()));
            }
        }
    }

    public static class Notify implements Runnable {

        @Override
        public void run() {
            // 加锁,获取lock的Monitor
            synchronized (lock) {
                // 获取lock的锁,然后通知,通知时不释放lock的锁
                // 直到当前线程释放了lock之后,WaitThread才从wait方法返回
                System.out.println(Thread.currentThread()   " hold lock. notify @ "   new SimpleDateFormat("HH:mm:ss").format(new Date()));
                lock.notifyAll();
                flag = false;
                SleepUtils.second(5);
            }
            // 再次加锁
            synchronized (lock) {
                System.out.println(Thread.currentThread()   " hold lock again. sleep @ "   new SimpleDateFormat("HH:mm:ss").format(new Date()));
                SleepUtils.second(5);
            }
        }
    }
}

结果为:

代码语言:javascript复制
Thread[WaitThread,5,main] flag is true. wait @ 15:05:55
Thread[NotifyThread,5,main] hold lock. notify @ 15:05:56
Thread[NotifyThread,5,main] hold lock again. sleep @ 15:06:01
Thread[WaitThread,5,main] flag is false. running @ 15:06:06

使用wait()、notify()以及notifyAll()时需要注意:

  • 使用wait()、notify()以及notifyAll()需要先调用对象加锁
  • 调用wait()方法后,线程状态由RUNNING变为WAITING,并将当前线程放置到对象的等待队列
  • notify()方法或者notifyAll()方法调用后,等待线程不会从wait()返回,需要调用notify()方法或notifyAll()的线程释放锁后,等待线程才有机会从wait()返回
  • 从wait()方法返回的前提是获得了调用对象的锁

0 人点赞