1、偏向锁
Java虚拟机中的实现中每个对象都有一个对象头,用于保存对象的系统信息,对象头中有一个成为MarkWord的部分,是实现锁的关键。当某一个线程获取锁以后,就会进入偏向锁,当线程再次请求这个锁的时候,无须在进行相关同步操作,从而节省了操场时间。如果在此期间其他线程进行了锁请求,则退出偏向锁。
--XX:UseBasicedLocking可以设置启用偏向锁。
当锁对象处于偏向模式的时候,对象头会记录获取锁的线程。
JavaTheard* | epoch | age | 1 | 01
该线程再次尝试获取锁的时候,通过Markword的线程信息就可以判断当前线程是否持有偏向锁。
偏向锁在竞争不激烈的情况下,对性能是有一定帮助的例如
public static List<Integer> numberLists = new Vector<>();
public static void showPianXiangBLocking() {
long begin = System.currentTimeMillis();
int count = 0;
int startTime = 0;
while (count < 10000000) {
numberLists.add(startTime);
startTime += 2;
count++;
}
long end = System.currentTimeMillis();
System.out.println(end - begin);
}
开启偏向锁
-XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0 -client -Xmx512m -Xms512m
-XX:BiasedLockingStartupDelay=0 表示虚拟机在启动以后立即开启偏向锁,如果不设置该参数的化,虚拟机默认开启后4秒后,才启用偏向锁。
上述配置,上述代码耗时 204ms.
不使用偏向锁耗时 1697ms.
当竞争激烈的时候,尝试关闭偏向锁。
2、锁消除。Java虚拟机在JIT编译的时候,去除不可能存在共享资源的竞争的锁,来节省毫无意义的请求锁的时间。虚拟机在运行时,通过逃逸分析技术,捕获不可能存在竞争却有申请锁的代码段,消除这些不必要的锁。
3、常见优化锁优化方式
1、减少锁的持有时间
2、减少锁粒度
3、锁分离
4、锁粗化
5、无锁。