Java-notify和wait的理解

2021-03-04  本文已影响0人  hello_world_cxm
package day0304;

public class TestWaitNotify {

    public static void main(String[] args) throws Exception{
        Object o = new Object();
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (o) {  //此时o的锁标记是空闲的,所以颁发给了t线程,t线程得以进入同步代码块 打印AB
                    System.out.println("A");
                    System.out.println("B");
                    o.notify(); //o呼叫在阻塞队列中的线程(即主线程)主线程离开o等待队列 但是没有拿到o的锁,调notify不会释放锁标识 然后继续往下执行
                    //打印完CD之后,t的锁标志就是被释放
                    System.out.println("C");
                    System.out.println("D");
                }
            }
        });
        t.start();
        
        synchronized (o) {
            System.out.println("1");
            System.out.println("2");
            //o是临界资源,多个线程来争夺使用权
            o.wait();  //主线程释放o的锁标记 并且主线程放弃了cpu,主线程进入了o的阻塞队列。随后时间片给了子线程t,
            System.out.println("3");
            System.out.println("4");
        }
    }

}

上面可以用去银行柜员机取钱的例子来说明,前提是柜员机有个大笼子罩着,笼子上面有把锁,取钱的人,只有拿到这把锁,才可以关闭笼子,进行独自取钱。且柜员机是每时每刻都要有人取钱。

首先主线程取到笼子的锁,并锁住了笼子,别的线程就无法进来切断主线程的原子操作,但是主线程取完1 2之后,忽然想出去离开柜员机打个电话,此时则意味着主线程放弃了取钱这个原子操作,并且放弃了cpu,此时主线程打完电话之后,发现笼子里面有线程t了,自己进不去,没办法,只能在笼子外的等待队列中等待,等待里面的人取完钱。
此时t线程已经取完1 2,并且大喊一声:你从等待队列中出列,来到笼子门口,我准备取完了。此时,t线程继续取钱,直到取完D,然后就释放了锁,释放了cpu,进入了终止状态。

此时主线程早已在笼子门口等待多时,然后获得笼子的那把锁,然后进去柜员机,继续取 3 4,因为刚才1 2已经取完。

最后取完3 4之后,主线程也进行终止状态,此时两个线程都已经结束,完。

上一篇下一篇

猜你喜欢

热点阅读