在JAVA的学习中,不少人会把sleep和wait都搞混,认为都是做线程的等待。比如方法sleep(long)和wait(long)就分不清,下面主要介绍下这俩者是什么,区别在哪。

首先需要明白很重要的一点!

sleep是Thread的方法,wait是Object的方法

由此可知,它俩的本质是不相同的。

区别一,sleep()线程控制自身流程。wait()用来线程间通信,使拥有该对象锁的线程等待直到指定时间或notify()。

Thread线程的方法,很简单,让线程休眠。使cpu让出该线程,等待时间过后,线程又重新进入排队恢复运行。

但是Object的方法就有问题了,Object是java的根基类,所有的对象都来源于此。所以wait方法的目的是让出对象锁,并进入线程等待池,等待一段时间或notify的唤醒并同时得到对象锁后运行。一般与notify一起使用。

区别二,sleep()方法的线程不会释放对象锁。wait()方法的线程会释放对象锁。

wait可以代替sleep吗?
答案不可以,如果直接调用wait会报出java.lang.IllegalMonitorStateException异常,原因是还没有得到对象锁,所以无法释放锁。

那么如何获得锁?
执行对象的某个同步实例方法。
执行对象对应类的同步静态方法。
执行对该对象加同步锁的同步块。
wait是通过控制对象锁来达到通信的目的,如果对象调用了wait,则会使线程交出该对象锁,然后处于等待状态。

比如在三个人看电视中,一个人持有遥控器进行换台,若想实现三个人轮流持有遥控器换台,则类似wait和notify的关系。三个人就是三个线程,电视就是对象,遥控器就是对象锁。首先一个人(线程)持有遥控器(锁),当电视发出wait命令后,这个人交出遥控器(锁),进入等待,电视(对象)发出notify命令后,处于等待的三个人(线程)随机一个获取遥控器(锁)

区别三,适用区域不同,wait只能放在同步语句块中才有意义。