wait 与 sleep
- 不同
- sleep 是
Thread
方法,而 wait 是Object
的方法 - sleep
不需要
强制和 synchronized 配合使用,但 wait需要
和 synchronized 一起用 - sleep 在睡眠的同时,
不会释放
对象锁的,但 wait 在等待的时候会释放
对象锁
- sleep 是
- 相同
- 如果wait(n,nanos),它们状态都是
TIMED_WAITING
- 如果wait(n,nanos),它们状态都是
wait 与 park
- 不同
- park,unpark
不必配合
Monitor(锁) 一起使用,,而 wait,notify 和 notifyAll必须配合
- park & unpark 是以线程为单位
指定
来【阻塞】和【唤醒】线程。而 notify 只能唤醒随机一个
等待线程,notifyAll 是唤醒所有
等待线程,就不那么【精确】 - park & unpark
可以先
unpark,而 wait & notify不能先
notify - park被打断后
不会清空
打断标记,想继续使用park需要清空标记为false。
- park,unpark
ReentrantLock 与 synchronized
- 不同
可中断
:lock.lockInterruptibly()和lock.trylock()。可处理死锁可超时
:tryLock()、tryLock(1, TimeUnit.SECONDS)。可处理死锁- 可以设置为
公平锁
:new ReentrantLock(true)。可处理饥饿 - 支持
多个条件变量
:await()、signal()、signalAll()
- 相同
- 与 synchronized 一样,都支持
可重入
- 与 synchronized 一样,都支持
CAS 与 synchronized
结合 CAS 和 volatile 可以实现无锁并发,适用于
线程数少、多核 CPU
的场景下。
- CAS 是基于
乐观锁
的思想:最乐观的估计,不怕别的线程来修改共享变量,就算改了也没关系,我吃亏点再 重试呗。 - synchronized 是基于
悲观锁
的思想:最悲观的估计,得防着其它线程来修改共享变量,我上了锁你们都别想 改,我改完了解开锁,你们才有机会。 - CAS 体现的是无锁并发、无阻塞并发,请仔细体会这两句话的意思
- 因为没有使用 synchronized,所以线程不会陷入阻塞,这是效率提升的因素之一
- 但如果竞争激烈,可以想到重试必然频繁发生,反而效率会受影响