Java wait 和 sleep 区别
很多人刚学Java的时候,都会把wait和sleep搞混——毕竟都是让线程“暂停一会儿”,乍看确实像双胞胎。但要是真用的时候乱调用,轻则程序卡顿,重则直接出bug,连报错信息都摸不着头脑。今天就用咱们日常带娃的例子,把这俩方法掰扯清楚,保证你下次用的时候不会再搞错。
谁能“主动让出资源”?
先想个场景:你带着孩子在公园玩,孩子突然说“我渴了要喝水”,这时候你手里正拿着刚买的冰淇淋,本来要继续走。

用wait就相当于:你会把冰淇淋的“临时占用权”暂时交出去——比如先把冰淇淋递给旁边的朋友照看,让其他想玩的人(其他线程)可以用这个“公园场地”(锁对象),等孩子喝完水(条件满足),你再回来接着拿冰淇淋继续走。
这个方法有个硬性要求:必须“拿着冰淇淋(锁)”才能操作——得先拿到对应的锁对象,不然调用wait会直接报错,就像你没带冰淇淋,孩子说要喝水,你没法临时把冰淇淋交出去一样。
再看sleep:就像你自己累了,找个长椅歇10分钟,不管孩子渴不渴、有没有人想用这个长椅,你占着的“冰淇淋(锁)”会一直攥着,这段时间别人没法用这个场地。这时候哪怕孩子已经喝完水了,你也得等10分钟歇够了,才能继续走。
而且Thread.sleep()是Thread类的方法,和锁没关系,不需要拿任何锁就能用,哪怕手里没东西,也能直接歇着。
谁会“自动醒”,谁得“等别人叫”?
还是用带娃的例子:
sleep就像你定了10分钟的闹钟,时间到了(休眠时长结束),你会自己醒过来,不管孩子有没有准备好,你都要继续走,属于“定时自动唤醒”。
wait就不一样了,它不会自己醒——你把冰淇淋交出去之后,只能等着孩子喊你“妈妈我喝完了”(也就是其他线程调用同一个锁对象的notify()或notifyAll()方法),你才能重新拿到冰淇淋,接着干活。要是没人喊你,你就一直等在原地,哪怕孩子渴了又渴,你也不会自己醒。
谁能在“任何地方用”,谁得“守规矩”?
再举个生活化的小例子:
sleep就像你上班摸鱼刷手机——不管是在工位、会议室还是茶水间,你想歇10分钟就歇,完全没限制,随便哪个场景都能用。
而wait就像你在公司的重要会议上:要是没拿到会议的“参与资格(锁对象)”,你根本没法在会上说“我要等一下”;只有拿到了资格,才能说“我先暂停一下,等大家聊完我再发言”。要是硬在没资格的时候说要等,只会被大家当成捣乱,程序也会直接抛出异常。
总结一句话记差别
这么一对比就简单了:wait是线程“主动放锁等条件”,得守规矩拿锁才能用,还得等别人喊才醒;sleep是线程“自己歇着占着锁”,在哪都能用,到点自己醒。
下次写代码的时候,要是需要让线程等某个条件(比如排队拿资源),就用wait;要是只是单纯让线程歇一会儿(比如定时任务的间隔),就用sleep,再也不会搞混啦。