一、sleep和wait的区别
sleep是Thread类的方法,导致此线程暂停执行指定时间,给其他线程执行机会,但是依然保持着监控状态,过了指定时间会自动恢复,调用sleep方法不会释放锁对象。当调用sleep方法后,当前线程进入阻塞状态。
wait方法是Object类里的方法,当一个线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时释放了锁对象,等待期间可以调用里面的同步方法,其他线程可以访问,等待时不拥有CPU的执行权,否则其他线程无法获取执行权。当一个线程执行了wait方法后,必须调用notify或者notifyAll方法才能唤醒,而且是随机唤醒,若是被其他线程抢到了CPU执行权,该线程会继续进入等待状态。
总结,在调用sleep()方法的过程中,线程不会释放对象锁;而当调用wait()方法的时候,线程会放弃对象锁;
二、传入参数
sleep()方法必须传入参数,参数就是休眠时间,时间到了就会自动醒来。
Thread.Sleep(0) 当前线程确实的被挂起了一下,让其他线程有机会优先执行。暂时放弃cpu,相当于一个让位动作
hread.Sleep(1) 本线程放弃cpu时间片,其他线程处理之后,再开始本线程
wait()方法可以传入参数也可以不传入参数,传入参数就是在参数结束的时间后开始等待,不穿如参数就是直接等待。
三、使用范围
wait、notify和notifyAll方法只能在同步方法或者同步代码块中使用;
sleep方法可以在任何地方使用。sleep是静态方法,只对当前对象有用;例如A线程中调用线程B.sleep(),线程A进入休眠,线程B无效;
四、使用sleep和wait的注意事项
1. sleep方法必须要捕获异常,而wait方法不需要捕获异常。
2. wait属于Object的成员方法,一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程;如果线程拥有某个或某些对象的同步锁,那么在调用了wait()后,这个线程就会释放它持有的所有同步资源,而不限于这个被调用了wait()方法的对象。
3. 调用wait方法和notify、notifyAll方法前必须获得对象锁,也就是必须写在synchronized(锁对象){......}代码块中。
4. 当线程A调用了wait方法后就释放了对象锁,否则其他线程无法获得对象锁,也就无法唤醒线程A。
5. 当this.wait()方法返回后,线程必须再次获得对象锁后才能继续执行。
6. 如果另外两个线程都在wait,则正在执行的线程调用notify方法只能唤醒一个正在wait的线程(公平竞争,由JVM决定)。
7. 当使用notifyAll方法后,所有wait状态的线程都会被唤醒,但是只有一个线程能获得锁对象,必须执行完while(condition){this.wait();}后才能获得对象锁。其余的需要等待该获得对象锁的线程执行完释放对象锁后才能继续执行。
8. 当某个线程调用notifyAll方法后,虽然其他线程被唤醒了,但是该线程依然持有着对象锁,必须等该同步代码块执行完(右大括号结束)后才算正式释放了锁对象,另外两个线程才有机会执行。