synchronized详解

sychronized

  • CAS概念

需求:创建100个线程,每个线程都对共享变量m增加100,100个线程运行结束时,m应该等于10000。

我们针对以上需求,有许多的实现方法,其中java为我们提供了一个原子类AtomicInteger,代码:

public class ViolateAtomic extends Thread{
    private static volatile AtomicInteger count = new AtomicInteger(0);
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            count.incrementAndGet();
        }
        System.out.println("线程"+ Thread.currentThread().getName()+":"+count);
    }

    public static void main(String[] args) {
        ViolateAtomic[] arr = new ViolateAtomic[100];
        for (int i = 0; i < 100; i++) {
            arr[i] = new ViolateAtomic();
        }

        for (int i = 0; i < 100; i++) {
            arr[i].start();
        }
    }
}

我们发现代码中并没有使用加锁的明代码,我们深入底层时发现incrementAndGet方法底层调用的compareAndSwap是native方法,即用C++代码实现的

机制:某个线程拿到共享变量E,经过计算得到V,此时再去拿到内存中的共享变量N,比较E和N是否一致,如果一致,则将计算后的V更新到内存中;

如果不一致,则拿到新的E,继续循环(但这种情况下,可能出现ABA问题,加个版本号字段即可解决该问题),具体参考下图

上述即被成为CAS,即无锁或自旋锁,该锁的机制不被操作系统掌控,所以是轻量级锁

 

  • 锁的升级过程

线程开始从无锁转为偏向锁,竞争加剧转为轻量级锁,当线程达到一定数量时经由操作系统管理,此时转为重量级锁

  • 对象在内存中的布局

4个部分组成:markword(锁信息,对象信息等)、classpointer、构造方法、补齐字节(总线读取内存中的数据放入寄存器中时,以16个字节读取内容效率更高)

  • synchronized
public class App 
{
    public static void main( String[] args )
    {
    	Object o = new Object();
    	System.out.println(ClassLayout.parseInstance(o).toPrintable());
    	synchronized (o) {
    		System.out.println(ClassLayout.parseInstance(o).toPrintable());
		}
    }
}

加锁前markword第一个字节为00000001,末位为01,此时为无锁态;加锁后为00,此时是轻量级锁,即自旋锁;锁的状态参考下图:

Hotspot锁状态及标志位

锁状态

说明

标志位

无锁态 0(区分是否偏向锁的标志位) 0 1
偏向锁当前线程指针JavaThread1(区分是否偏向锁的标志位) 0 1
轻量级锁指向线程中LR指针0 0
重量级锁指向互斥量的指针1 0
GC标记信息CMS过程用到的标记信息1 1

 

  • 总结

线程创建从无锁转为偏向锁,竞争加剧时,偏向锁转向轻量级锁(自旋锁),此时多个线程会生成自己的LockRecord以CAS的方式改变对象的对象头信息(即markword)进行加锁,即为synchronized的本质

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值