当前位置: 首页 > 科技观察

漫画:如何证明Sleep不释放锁,而Wait释放锁?_0

时间:2023-03-17 11:44:08 科技观察

等待锁示例publicclassWaitDemo{privatestaticObjectlocker=newObject();publicstaticvoidmain(String[]args)throwsInterruptedException{WaitDemowaitDemo=newWaitDemo();//启动一个新线程,防止主线程休眠newThread(()->{try{waitDemo.doWait();}catch(InterruptedExceptione){e.printStackTrace();}}).start();线程.睡眠(200);//这行本身没有任何意义,是保证wait()先于notify()执行waitDemo.doNotify();}/***执行wait()*/privatevoiddoWait()throwsInterruptedException{synchronized(locker){System.out.println("等待开始");储物柜。等待();System.out.println("等待结束。");}}/***执行notify()*/privatevoiddoNotify(){synchronized(locker){System.out.println("notifystart.");锁柜通知();System.out.println("通知结束。");}}}上面程序的执行结果是:waitstart.notifystart.notifyend.waitend。代码分析从上面的代码可以看出,我们给wait()和notify()这两个方法设置了同一个锁(locker),但是调用wait()方法后locker的锁被释放了,所以程序可以正常执行notify()的代码,因为是同一个锁,如果不释放锁,则不会执行notify()代码,从打印的结果也可以确认(结果输出的顺序),所以wait()方法根据上述情况释放锁睡眠锁示例publicclassWaitDemo{privatestaticObjectlocker=newObject();publicstaticvoidmain(String[]args)throwsInterruptedException{WaitDemowaitDemo=newWaitDemo();//启动一个新线程,防止主线程休眠newThread(()->{synchronized(locker){try{System.out.println("sleepstart.");Thread.sleep(1000);System.out.println("sleepend.");}catch(InterruptedExceptione){e.printStackTrace();}}}).start();线程.睡眠(200);waitDemo.doNotify();}/***执行notify()*/privatevoiddoNotify(){synchronized(locker){System.out.println("notifystart.");锁柜通知();System.out.println("通知结束。");}}}上面程序的执行结果是:sleepstart。睡眠结束。通知开始。通知结束。代码分析从上面的代码我们可以看出sleep(1000)方法(行号:11)被执行,调用notify()方法并没有获得locker锁。从上面的执行结果可以看出,notify()方法是在sleep(1000)方法执行完之后执行的。因此可以证明,调用sleep()方法并不会释放锁。知识延伸1.sleep和wait有什么区别?sleepandwait是几乎所有面试必问的问题,但要正确回答似乎没那么简单。关于sleep和wait的区别,通常的回答是:wait必须和synchronize一起使用,sleep不需要;进入wait状态的线程可以通过notify和notifyAll线程唤醒,而处于sleep状态的线程不能通过notify方法唤醒;wait通常是有条件地执行的,线程会一直处于等待状态,直到某个条件变为真,而sleep只是让你的线程进入休眠状态;wait方法将释放对象锁,但sleep方法不会。但是上面的回答显然忽略了一个重要的区别。调用wait方法后线程会变成WATING状态,调用sleep方法后线程会变成TIMED_WAITING状态。2.wait可以用在static方法中吗?为什么?不行,因为wait方法是实例方法(不是静态方法),所以不能在static中使用。源码如下:publicfinalvoidwait()throwsInterruptedException{wait(0);}3.wait/notify可以不使用synchronized吗?为什么?不会,因为如果不和synchronized一起使用,程序会报错,如下图:wakeup,详见:https://juejin.im/post/5e6a4d8a6fb9a07cd80f36d1总结在本文中,我们使用synchronized锁定同一个对象来测试wait和sleep方法,然后通过执行结果的顺序来证明:wait方法将释放锁,但睡眠方法不会。同时,我们也聊了几个关于wait和sleep的常见面试题。我希望这篇文章可以帮助你。