sleep(long n) 和 wait(long n) 的区别
sleep(long n) 和 wait(long n) 的区别
- sleep 是 Thread 方法,而 wait 是 Object 的方法
- sleep 不需要强制和 synchronized 配合使用,但 wait 需要 和 synchronized 一起用
- sleep 在睡眠的同时,不会释放对象锁的,但 wait 在等待的时候会释放对象锁
park unpark 与 wait notify
- wait, notify 和 notifyAll 必须配合 Object Monitor 一起使用,而 park,unpark 不必
- park & unpark 是以线程为单位来【阻塞】和【唤醒】线程,而 notify 只能随机唤醒一个等待线程,notifyAll 是唤醒所有等待线程,就不那么【精确】
- park & unpark 可以先 unpark,而 wait & notify 不能先 notify
重新理解线程状态转换
假设有线程 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
- 竞争锁成功,t 线程从
情况 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 线程从
类似的还有 t.join(long n)
, Thread.sleep(long n)
,LockSupport.parkNanos(long nanos)
情况 6 RUNNABLE <--> BLOCKED
- t 线程用
synchronized(obj)
获取了对象锁时如果竞争失败,从RUNNABLE --> BLOCKED
情况 7 RUNNABLE <--> TERMINATED
当前线程所有代码运行完毕,进入 TERMINATED