synchronized是什么?
java里面一个解决并发访问的关键字,可以保证在同一时刻只有一个线程运行synchronized修饰的同步代码块或者方法
实现原理
jvm层面来说synchronized可以修饰方法也可以修饰代码块,被synchronized修饰的方法在常量池会有一个ACC_SYNCHRONIZED的标记,如果有线程要进入方法看到有这个标记的话就会尝试获取监视器锁,获取成功了才能进入方法,否则就会被阻塞,(如果发生了异常会在异常抛出之前释放监视器锁)
同步代码块使用moniterenter和moniterexit两条指令实现(ObjectMoniter的enter和exit方法),一个相当于加锁一个相当于释放锁,每个对象都维护了一个锁的计数器,当一个线程执行moniterenter的时候这个计数器就会加一,如果再次获取锁也就是重入的话就会再次加一,当计数器变成0的时候锁才会被释放
在操作系统层面使用的是mutex lock这种重度锁来实现的,每次加锁解锁都有用户态和内核态的开销,在jdk1.6之后会有一个锁升级的过程,就不用每次都使用这种重度锁
jdk1.6对synchronized其他优化,锁消除/粗化,自适应自旋锁(1.6默认开启)
如果编译器通过逃逸分析发现锁只会被一个线程占用,也就是不会发生竞争,就会将锁消除
如果多个同步块占用的是同一个锁,为了避免频繁的加锁解锁,会加大锁的粒度
