sleep()方法:
功能:
sleep()方法是Thread类的方法,线程通过调用该方法,进入休眠状态主动让出CPU,从而CPU可以执行其他的线程。经过sleep指定的时间后,CPU回到这个线程上继续往下执行。
如何当前线程进入了同步锁,sleep()方法并不会释放锁。即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。
使用场合:
线程的调度执行是按照其优先级的高低顺序进行的,当高级别的线程未死亡时,低级别的线程没有机会获得CPU资源。有时优先级高的线程需要优先级低的线程完成一些辅助工作或者优先级高的线程需要完成一些比较费时的工作,此时优先级高的线程应该让出CPU资源,使得优先级低的线程有机会执行。为了达到这个目的,优先级高的线程可以在自己的run()方法中调用sleep方法来使自己放弃CPU资源,休眠一段时间
注意:
如果线程在休眠时被打断,JVM就会抛出InterruptedException异常。因此,必须在try-catch语句块中调用sleep方法。
wait()方法:
功能:
wait()方法可以中断线程的运行,使本线程等待,暂时让出CPU的使用权,并**允许其他线程使用这个同步方法。其他线程如果在使用这个同步方法时不需要等待,那么它使用完这个方法的同时,应该用notifyAll()方法通知所有由于使用了这个同步方法而处于等待的线程结束等待,曾中断的线程就会从刚才中断处继续执行这个同步方法(并不是立马执行,而是结束等待),并遵循“先中断先继续”的原则。wait方法释放了锁
wait是指在一个已经进入了同步锁的线程内**,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁)
使用场合:
当一个线程使用的同步方法中用到某个变量,而此变量又需要起亚线程修改后才能符合本线程的需要,那么可以在同步方法中使用wait()方法
注意:
wait()、notify()和notifyAll()都是Object类的final方法,被所有的类继承且不允许重写的方法。特别需要注意的是,不可以在非同步方法中使用上述三个方法。
sleep()和wait()不同点:
- 这两个方法来自不同的类分别是Thread和Object。
- 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
- sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常。
- 为什么wait(),notify()方法要和synchronized一起使用?
因为wait()方法是通知当前线程等待并释放对象锁,notify()方法是通知等待此对象锁的线程重新获得对象锁,然而,如果没有获得对象锁,wait方法和notify方法都是没有意义的,即必须先获得对象锁,才能对对象锁进行操作,于是,才必须把notify和wait方法写到synchronized方法或是synchronized代码块中了。 - wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用(使用范围)
- sleep 是线程类(Thread)的静态方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep 不会释放对象锁。
wait 是Object 类的成员方法,对此对象调用wait 方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify 方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。 - 还有用法上的不同是:sleep(milliseconds)可以用时间指定来使他自动醒过来,如果时间不到你只能调用interreput()来强行打断;wait()可以用notify()直接唤起。
- 在java.lang.Thread类中,提供了sleep(),
而java.lang.Object类中提供了wait(),notify()和notifyAll()方法来操作线程
sleep()可以将一个线程挂起,参数可以指定一个时间
而wait()可以将一个线程挂起,直到超时或者该线程被唤醒
sleep()和wait()共同点:
都是使线程暂停一段时间的方法。