- 线程的概念、启动方式、常用方法
- Synchronized(Object)线程同步
-- 不能用String常量或者String数据类型,Integer,Long。不能用基础数据类型
-- “object”
- 线程同步
-- synchronized
- 锁- 锁的是对象不是代码
- 普通方法 锁的是this(当前对象) static对象锁的是 xx.class
- 锁定方法与非锁定方法 可以同时执行
- 锁升级 如果锁定某个对象 在对象头上的某两位指定锁的是什么类型的锁。在对象头上记录着哪个线程谁抢了这把锁
-- 偏向锁->自旋锁->重量级锁 这三种锁 锁的粒度依次递增
首先是无锁的状态,线程来了先不尝试加锁,markword 只是记录这个线程ID (偏向锁)。这样认为这个对象是这个线程独有的,再来申请锁时就先倾向于同样的这个线程。这种情况的锁偏向于第一次拿到这把锁的线程。如果线程争用,下次来的这个线程是新的线程则进行锁升级,首先尝试升级为 自旋锁,自旋10次以后,升级为重量级锁 - OS Operator
自旋是积极的排队,占用CPU时间的。Wait queue是不占用CPU时间的,不消耗CPU
什么时候用自旋锁,什么时候用重量级锁?
执行时间短(加锁代码),线程数少,用自旋锁
执行时间长,线程数多,用系统锁,就是重量级锁
Synchronized加锁 效率低,某种情况下或条件下向系统申请重量级锁
Automatic 不加锁效率高
LongAdder 内部是用分段锁 锁资源的,高并发、线程多的情况下有优势。采用CAS操作