synchronized: 锁定对象(在堆内存中),不能用String常量,Long,Integer 等基本类型;即保证了原子性又保证了可见性
原理
hotspot实现: hotspot是这样实现的,在一个对象的头64位,拿出2位来记录这个对象是否被锁定,并存入线程ID(mark word)
hotsport实现步骤
1.第一次 markword 记录这个线程ID,没有其他线程访问 (偏向锁)
2.线程争用 (自旋锁)-用户空间,会占用CPU
其他线程争用,首先是自旋(理解为while循环心跳检测,超过10次升级为重量级锁)
3.升级为 (重量级锁)- 内核空间,不会占用CPU
重量级锁会去操作系统申请锁资源,经过OS,进入等待队列,不再占用CPU
注意:
1.锁一旦升级了,就不能降级
2.执行时间长的,线程数多,用重量级锁(系统锁)
3.执行时间短的(加锁代码),线程数少,用自选锁
实例一、sycnchronized锁定某个对象
//hotspot是这样实现的,在一个对象的头64位,拿出2位来记录这个对象是否被锁定(mark word)
private int count = 10;
Object o = new Object();
public static void main(String[] args) {
}
private void syncTest(){
synchronized (o){
//任何线程要执行以下代码,都必须先拿到锁
count --;
}
}