用代码探究 java 中的偏向锁

一、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
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值