synchronized

一、简介

        synchronized俗称 ‘同步锁’,是java程序解决并发问题的同步方案。

        主要作用有三种:

        原子性:确保线程互斥地访问同步代码;
        可见性:保证共享变量的修改能够及时可见,其实是通过Java内存模型中的“对一个变量unlock操作之前,必须要同步到主内存中;如果对一个变量进行lock操作,则将会清空工作内存中此变量的值,在执行引擎使用此变量前,需要重新从主内存中load操作或assign操作初始化变量值” 来保证的.
        有序性:有效解决重排序问题.

二、实现底层原理

        synchronized的实现主要依赖于虚拟机jvm。以HotSpot 虚拟机为例,对象在虚拟机中主要三块区域:对象头、实例数据和对齐填充。Mark Word就存在于对象头中,包含 哈希码、GC分代年龄、锁状态标识、是否偏向锁等信息。

monitor锁的竞争过程

        在Java虚拟机(HotSpot)中,monitor是由ObjectMonitor实现的,就好比一个监视器,由许多组件组成。

        1、当多个线程同时访问一段同步代码时,会先进入contentionList进行等待;

        2、当线程获取到对象的monitor 后进入 _Owner 区域,并把monitor中的owner变量设置为当前线程,同时monitor中的计数器count加1;

        3、若线程调用 wait() 方法,将释放当前持有的monitor,owner变量恢复为null,count自减1,同时该线程进入 WaitSe t集合中等待被唤醒;

        4、等待的线程获得锁monitor,重复2的操作;

        5、若当前线程执行完毕也将释放monitor并复位变量的值,以便其他线程进入获取monitor。

三、锁的升级

        锁是为了解决并发冲突问题,但加锁的同时,也会带来性能的降低。synchronized 在jdk1.5之前是重量级锁,性能很低;但随着jdk1.6版本的优化,引入了偏向锁、轻量级锁,锁的状态,降低了锁了重量级。

        1、偏向锁

        当一个线程访问同步块并获取对象的锁时,会将锁的标记记录在线程的栈帧中,并将对象头中的Thread ID设置为当前线程的ID

        2、轻量级锁

        一个或多个线程通过CAS的方式去竞争锁,如果获得锁,则表示线程获取了轻量级锁,并继续执行同步块;如果CAS失败,说明有竞争,会通过自旋等待。

        3、重量级锁

        如果自旋等待不成功,虚拟机会将轻量级锁升级为重量级锁。在这种状态下,虚拟机会将线程阻塞,并使用操作系统的互斥量来实现锁的释放和获取。

四、与ReetanrentLock区别

        1、reentrantLock使用起来比较灵活,但是必须有释放锁的配合动作。

   2、reentrantLock必须手动获取与释放锁,而 synchronized 不需要手动释放和开启锁。

   3、reentrantLock只适用于代码块锁,而 synchronized 可以修饰类、方法、变量。

        4、reentrantLock可实现公平锁和非公平锁,而synchronized只能是非公平锁。

        5、reentrantLock通过Unsafe 实现加锁的,而synchronized则是通过jvm的Mark Word。

  • 28
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值