一、synchronized
相信对于 java 开发这个关键字并不陌生,它主要是用来进行线程间通信和保证共享数据的一致性,但是在刚入行的时候听老前辈说过尽量少使用 synchronized 这个关键字,多使用 juc 包下的 Lock 来替代它,因为使用 synchronized 的成本很高,可能在当时他说的是对的,但是在现在看来这句话不一定是对的,为什么这么说呢,请看下面的例子(使用 jdk 版本:1.8.0_231)
public class SyncBeforeJdk16Test {
@Test
public void syncTest(){
Object lock = new Object();
Lock jucLock = new ReentrantLock();
//---------------------- before -------------------------------
for (int i = 0; i < 2; i++) {
new Thread(()->{
synchronized (lock){
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
//---------------------- end -------------------------------
long start = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
synchronized (lock){
i ++;
}
}
System.out.println("sync time used " + (System.currentTimeMillis() - start));
long jucStart = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
jucLock.lock();
i ++;
jucLock.unlock();
}
System.out.println("juc time used " + (System.currentTimeMillis() - jucStart));
}
}
代码应该不难看懂,就是执行了 1E 次的 i++ 操作,只不过中间一个通过 synchronized 加锁执行一个通过 Lock 加锁执行,start 到 end 间的代码好像跟下面代码的执行半毛钱关系没有,至于为什么要这么写我待会跟你解释
执行结果如下:
这么看来老前辈好像没有骗我,使用 juc 下的 Lock 确实比 synchronized 关键字快得多,那么为什么说现在看来不一定是对的呢,现在把 start 跟 before 中间的代码注掉看一下执行效果
你会发现使用 synchronized 关键字执行时间少了一半多
那么在执行的 vm 参数中加上这个 -XX:BiasedLockingStartupDelay=0 再试下呢(参数前面有横杠不要省略)
令人吃惊的事情出现了,synchronized 执行时间比 juc 快了 7 倍!这为什么跟老前辈说的不一样了呢?还有 start 跟 before 中间的代码作用是什么?vm 参数的作用又是什么?下面就开始介绍 jdk 1.6 之后对 synchronized 关键字究竟做了哪些优化
二、jdk 1.6 对 synchronized 的优化
1、对象头
说到 jdk1.6 对 synchronized 关键字的优化,就不得不提一下对象头是什么,下面来看一下 jdk 官方对于对象头的解释https://wiki.openjdk.java.net/display/HotSpot/Synchronization#Synchronization-Agesen99
In the Java HotSpot™ VM, every object is preceded by a class pointer and a header word.
The header word, which stores the identity hash code as well as age and marking bits for generational garbage collection, is also used to implement a thin lock scheme
Synchronization affects multiple parts of the JVM: Th