wait和sleep的区别
文章内容来自《java并发编程详解》,这些是笔记。
注意事项
- wait属于可中断方法,当前线程一旦调用wait方法进入阻塞状态,其他线程可以使用interrupt方法将其打断。可中断方法被打断后会抛出中断异常InterruptedException,同时interrupt标识也会被删除。
- 线程执行wait方法后,会加入与之对应的wait set中,每一个对象的monitor都有一个与之关联的wait set
- 当线程进入wait set之后,notify方法可以将其唤醒,也就是从wait set中弹出,同时中断wait中的线程也会将其唤醒。
- 必须在同步方法中使用wait 和notifyf方法,因为wait和notify的前提条件是必须持有同步方法的monitor的所有权。
- 同步代码的monitor必须与执行的wait notify方法的对象一致,简单的说就是用哪个对象的monitor进行同步,就执行用哪个对象进行wait和notify方法。
wait和sleep的区别
-
wait和sleep方法都可以使线程进入阻塞状态。
-
wait和sleep方法都是可中断方法,被中断后都会收到中断异常。
-
wait 是Object的方法,而sleep是Thread特有的方法。
-
wait方法必须执行在同步方法中执行,而sleep不需要。
-
线程在同步方法中执行sleep方法时,不会释放monitor的锁。而wait方法则会释放monitor的锁
-
sleep方法短暂休眠后会主动退出阻塞(会进入TIMED_WAITING状态),而wait方法(没有指定wait时间的话)则需要被其他线程中断之后才能退出阻塞(会进入WAITING状态),设置时间就会进入TIMED_WAITING状态。
关于最后一点的代码验证
public class ThreadisInterrupt { public static void main(String[] args) throws InterruptedException { Object object=new Object(); Thread thread=new Thread(()->{ /*synchronized (object) { try { object.wait(20000); } catch (InterruptedException e) { e.printStackTrace(); } }*/ /*synchronized (object) { try { object.wait(); } catch (InterruptedException e) { e.printStackTrace(); } }*/ try { Thread.sleep(500000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }); thread.start(); while(true) { System.out.println(thread.getState()); //TimeUnit.SECONDS.sleep(1); } } }