一、概念
sleep
线程进入阻塞状态,不能得到CPU执行时间,只有等待时间够长之后才会使线程重新进入可执行状态。 调用sleep时线程不会释放他的锁标识。
wait
wait需和notify配合使用,线程调用wait后进入阻塞状态。wait有两个重载方法,一个是包含固定时长参数,另一个不包含固定时长参数。
- 包含固定时长参数时在等待时长超出或者调用notify都会使线程重新进入可执行状态;
- 不包含固定时长参数的只有调用notify才会重新进入可执行状态。
wait 和 notify需要使用在synchronized函数或块中,当进入wait时,同步块中的同步数据可以被其他线程使用。
二、区别
- 两者最主要的区别在于:sleep 方法没有释放锁,而 wait 方法释放了锁 。
- 两者都可以暂停线程的执行。
- Wait 通常被用于线程间交互/通信,sleep 通常被用于暂停执行。
- wait() 方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的 notify() 或者 notifyAll() 方法。sleep() 方法执行完成后,线程会自动苏醒。或者可以使用 wait(long timeout)超时后线程会自动苏醒。
- wait()方法的调用必须放在synchronized方法或synchronized块中
三、扩展
notify
- notify()方法会唤醒一个等待当前对象的锁的线程。 如果多个线程在等待,它们中的一个将会选择被唤醒。这种选择是随意的。
- 被唤醒的线程是不能被执行的,需要等到当前线程放弃这个对象的锁。 被唤醒的线程将和其他线程以正常的方式进行竞争,来获得对象的锁,没有什么优先权。
- notify方法和wait一样,是需要放在synchronized方法或synchronized块中。
- 调用notifyAll()方法能够唤醒所有正在等待这个对象的monitor的线程。
yield
Yeild只会使当前线程结束执行状态,功能相当于提前让线程的CPU时间使用完毕。当前的线程继续进入可执行队列中,所以有可能当前的线程会投入可执行队列后会立即进行执行。Wait可以使低优先级的线程得到执行时间,但Yeild只会使同优先级的线程得到执行时间。
suspend
Suspend需和resume配套使用。Suspend使当前线程阻塞,且不会自动回复。只有调用resume才会使当前的线程恢复可执行状态。