一、synchronize
synchronize 的锁标记存在对象头里面
锁升级从上到下
锁升级的本质是作者对线程安全和性能的平衡
无锁——加锁
当只有A线程时:
偏向锁 单线程,不存在竞争,该线程获取锁后,不再需要抢占
当线程B加入,开始抢占锁时,锁首先升级为轻量级锁,进行自旋抢占,
轻量级锁
避免线程阻塞,通过自旋锁实现(cas),自旋是消耗cpu的,
自旋次数少时cas的消耗比唤醒锁的性能开销要小
1.7开始有自适应自旋,性能安全和性能的平衡
当B自旋次数内没有抢占到锁,升级为重量级锁,
重量级锁
有锁,把阻塞线程加入到等待队列
synchronized锁的作用范围:
synchronized 锁的本质是锁的对象,如下面代码,
public class SynchronizeDemo {
/* *
* @Description:修饰实例方法
*/
public synchronized void m1(){
}
/* *
* @Description:修饰代码块(当前对象)
*/
public void m2(){
synchronized (this){
}
}
/* *
* @Description:修饰代码块(类对象)
*/
public void m3(){
synchronized (SynchronizeDemo.class){
}
}
/* *
* @Description:修饰静态方法
*/
public static synchronized void m4(){
}
public static void main(String[] args) {
SynchronizeDemo sd1 = new SynchronizeDemo ();
SynchronizeDemo sd2 = new SynchronizeDemo ();
new Thread(()->{ //线程A
sd1.m1 ();
// sd1.m2 ();
// sd1.m3 ();
// sd1.m4 ();
}).start ();
new Thread(()->{ //线程B
sd1.m1 ();
// sd1.m2 ();
// sd1.m3 ();
// sd1.m4 ();
}).start ();
new Thread(()->{ //线程C
sd2.m1 ();
// sd2.m2 ();
// sd2.m3 ();
// sd2.m4 ();
}).start ();
}
}
当调用m1方法时:
线程A和线程B之间有锁竞争,和线程C之间没有锁的竞争。
当调用m2方法时:
线程A和线程B之间有锁竞争,和线程C之间没有锁的竞争。
当调用m3方法时:
线程A和线程B之间有锁竞争,和线程C之间也有锁的竞争。
当调用m4方法时:
线程A和线程B之间有锁竞争,和线程C之间也有锁的竞争。
CAS
pompareAndSwap(old,expect,update)
old:内存中的对象
expect:比较值
update:更新的值
返回值为true /false