sleep(long n) 和 wait(long n) 的区别

sleep(long n) 和 wait(long n) 的区别

  1. sleep 是 Thread 方法,而 wait 是 Object 的方法
  2. sleep 不需要强制和 synchronized 配合使用,但 wait 需要 和 synchronized 一起用
  3. sleep 在睡眠的同时,不会释放对象锁的,但 wait 在等待的时候会释放对象锁

park unpark 与 wait notify

  1. wait, notify 和 notifyAll 必须配合 Object Monitor 一起使用,而 park,unpark 不必
  2. park & unpark 是以线程为单位来【阻塞】和【唤醒】线程,而 notify 只能随机唤醒一个等待线程,notifyAll 是唤醒所有等待线程,就不那么【精确】
  3. park & unpark 可以先 unpark,而 wait & notify 不能先 notify

重新理解线程状态转换

sleep(long n) 和 wait(long n) 的区别

假设有线程 Thread t

情况 1 NEW --> RUNNABLE

当调用 t.start()方法时,由 NEW --> RUNABLE

情况 2 RUNNABLE <--> WAITING

t 线程 用 synchronized(obj)获取了对象锁后

  • 调用 obj.wait()方法时,t 线程从 RUNNABLE --> WAITING
  • 调用 obj.notify()obj.notifyAll()t.interrupt
    • 竞争锁成功,t 线程从 RUNNABLE --> WAITING
    • 竞争锁失败,t 线程从 RUNNABLE --> BLOCKED

情况 3 RUNNABLE <--> WAITING

  • 当前线程调用 t.join()方法时,当前线程从 RUNNABLE --> WAITING
    • 注意是当前线程在 t 线程对象的监视器上等待
  • t 线程运行结束,或调用了当前线程的 interrupt()时,当前线程从 WAITING --> RUNNABLE

情况 4 RUNNABLE <--> WAITING

  • 当前线程调用 LockSupport.park()方法会让当前线程从 RUNNABLE --> WAITING
  • 调用 LockSupport.park(目标线程)或调用了当前线程的 interrupt()时,当前线程从 WAITING --> RUNNABLE

情况 5 RUNNABLE <--> TIMED_WAITING

t 线程用 synchronized(obj)获取了对象锁后

  • 调用 obj.wait(long n)方法时,t 线程从 RUNNABLE --> TIMED_WAITING
  • t 线程等待时间超过了 n 毫秒,或调用 obj.notify()obj.notifyAll()t.interrupt
    • 竞争锁成功,t 线程从 TIMED_WAITING --> RUNNABLE
    • 竞争锁失败,t 线程从 TIMED_WAITING --> BLOCKED

类似的还有 t.join(long n)Thread.sleep(long n)LockSupport.parkNanos(long nanos)

情况 6 RUNNABLE <--> BLOCKED

  • t 线程用 synchronized(obj)获取了对象锁时如果竞争失败,从 RUNNABLE --> BLOCKED

情况 7 RUNNABLE <--> TERMINATED

当前线程所有代码运行完毕,进入 TERMINATED