虽然两者都是用来暂停当前运行嘚线程但是 sleep() 实际上只是短暂停顿,因为它不会释放锁而 wait() 意味着条件等待,这就是为什么该方法要释放锁因为只有这样,其他等待的線程才能在满足条件时获取到该锁
结合synchronized会更好的理解sleep()和wait()这两个方法,当然也就知道了他们的区别了这篇博客就一起学习这两个方法
sleep() 方法是线程类(Thread)的静态方法,让调用线程进入睡眠状态让出执行機会给其他线程,等到休眠时间结束后线程进入就绪状态和其他线程一起竞争cpu的执行时间。
因为sleep() 是static静态的方法他不能改变对象的机锁,当一个synchronized块中调用了sleep() 方法线程虽然进入休眠,但是对象的机锁没有被释放其他线程依然无法访问这个对象。
下面用一个例子来演示:
僦定义了两个方法 mSleep()方法会让调用线程休眠3秒,mWait() 就打印一句话两个方法都使用了同步锁。
创建了一个Service对象并赋值给mService还创建了两个线程並传入mService,也就是说两个线程启动后调用的是同一个Service对象的方法。
等到sleepThread线程执行完毕(休眠结束)后释放了同步锁waitThread线程拿到了同步锁,會继续执行mWait才会被调用。
如果sleepThread释放了机锁的话waitThread 的任务会马上得到执行。从打印结果可以看出waitThread 的任务是3秒钟之后才得到执行。
同步锁锁住的是一个对象。如果一个线程拿到了一个对象的机锁去执行一段同步代码块了那么其他线程都不能执行这个对象的其他同步代码塊。
在这个例子中就是sleepThread线程拿到了service对象的同步锁进入后休眠,但没有释放机锁那么waitThread线程是不能执行这个service对象的其他同步代码块的,也僦就是不能进入这一段代码
相信现在你已经理解了sleep方法没有释放机锁会带来什么结果了那么继续wait
wait()是Object类的方法,当一个线程执行到wait方法时它就进入到一个和该对象相关的等待池,同时释放对象的机锁使得其他线程能够访问,可以通过notifynotifyAll方法来唤醒等待的线程
下面修改程序如下所示:
waitThread线程启动起来,然后waitThread线程进入等待状态并释放了Service对象的锁,这时sleepThread也启动了来到了mSleep方法的同步代码块,因为之前的waitThread线程已經释放了Service对象的机锁sleepThread可以拿到对象锁,所以mSleep方法是会被马上调用的然后sleepThread线程就是进入了睡眠状态,等到3秒休眠结束后调用notifyAll()唤醒了waitThread线程
综上所诉:
sleep() 和 wait() 的区别就是 调用sleep方法的线程不会释放对象锁,而调用wait() 方法会释放对象锁
虽然两者都是用来暂停当前运行嘚线程但是 sleep() 实际上只是短暂停顿,因为它不会释放锁而 wait() 意味着条件等待,这就是为什么该方法要释放锁因为只有这样,其他等待的線程才能在满足条件时获取到该锁