java使用wait(),notify(),notifyAll()实现等待/通知机制

public class WaitNotify {
    static boolean flag=true;
    static Object lock=new Object();

    static class Wait implements Runnable{
        @Override
        public void run() {
            synchronized (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){
                    }
                }
            }
            System.out.println(Thread.currentThread()+" flag is false.running " +
                    "@"+new SimpleDateFormat("HH:mm:ss").format(new Date()));

        }
    }

    static class Notify implements Runnable{
        @Override
        public void run() {
            synchronized (lock) {
                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(String.format(Thread.currentThread() + " hold lock again. sleep " +
                        "@" + new SimpleDateFormat("HH:mm:ss").format(new Date())));
                SleepUtils.second(5);
            }
        }
    }

    public static void main(String[] args) {
        Thread waitThread=new Thread(new Wait(),"WaitThread");
        waitThread.start();
        try {
            TimeUnit.SECONDS.sleep(1);
        }catch (InterruptedException e){

        }
        Thread notifyThread=new Thread(new Notify(),"NotifyThread");
        notifyThread.start();
    }
}

程序执行结果:

Thread[WaitThread,5,main] flag is true. wait @ 14:41:12
Thread[NotifyThread,5,main] hold lock. notify @ 14:41:13
Thread[NotifyThread,5,main] hold lock again. sleep @14:41:18
Thread[WaitThread,5,main] flag is false.running @14:41:23

1.使用wait(),notify(),notifyAll()方法之前,要获取同一个对象的锁。

2.调用wait()方法之后,线程会从RUNABLE状态变为WAITING状态,并会释放对象锁,并会将线程移入到对象的等待队列中。

3.notify()和notifyAll()调用之后,等待的线程的wait方法并不会立马返回,需要锁空闲的时候,等待的线程获取了锁,wait()方法才会返回。

4.调用了notify()和notifyAll()方法之后,notify会将一个线程从等待队列放置到同步队列,同步队列是因为锁被占有而处于BLOCKED阶段的线程,notifyAll则是将等待队列中所有的线程都移动到同步队列,这两个方法都是将线程从WAITING状态变为BLOCKED状态。

5.从wait方法返回的条件是获得了调用对象的锁。

该程序的执行流程是首先WaitThread获取了lock,然后waitThread调用wait方法,会释放锁,并将锁移入等待队列,接着notifyThread会获取锁,调用notifyAll,但是wait()方法并没有返回,因为lock没有释放,notifyThread会睡眠5秒,这时同步队列中有两个线程要获取lock,一个是notifyThread,一个是WaitThread,结果显示是notifyThread又重新获取了锁,所以这时的wait方法依然不能返回,当notifyThread执行完了之后,释放锁,waitThread获取了锁,并且wait方法返回,waitThread执行完成。

猜你喜欢

转载自www.cnblogs.com/xiaobaituyun/p/10621609.html