锁及Synchronized实现原理分析

Java锁的定义

锁的内存语义
  • 锁可以让临界区互斥执行,还可以让释放锁的线程向同一个锁的线程发送消息;
  • 锁的释放要遵循Happens-before原则(锁规则:解锁必然发生在随后的加锁之前);
  • 锁在Java中的具体表现是Synchronized和Lock;
锁的释放

线程A释放锁后,会将其共享变更操作刷新到主内存中。
在这里插入图片描述

锁的获取

线程B获取锁时,JVM会将该线程的本地内存置为无效,被监视器保护的临界区代码必须从主内存中读取共享变量。
在这里插入图片描述

锁的释放和获取
  • 线程A释放一个锁,实质是线程A告知下一个获取到该锁的某个线程其已变更该共享变量。
  • 线程B释放一个锁,实质是线程B得到了线程A告知其(在释放锁之前)变更共享变量的消息。
  • 线程A释放锁,随后线程B竞争得到该锁,实质是线程A通过主内存向线程B发消息告知其变更了该共享变量。

Synchronized的综述

  • 同步机制:Synchronized是Java同步机制的一种实现,即互斥锁机制,它所获得的锁叫做互斥锁。
  • 互斥锁:指的是每个对象的锁一次只能分配给一个线程,同一时间只能由一个线程占用
  • 作用:Synchronized用于保证同一时刻只能由一个线程进入到临界区,同时保证共享变量的可见性、原子性和有序性。
  • 使用:当一个线程试图访问同步代码方法(块)时,它首先必须得到锁,退出或抛出异常时必须释放锁。

Synchronized的使用

在这里插入图片描述

Synchronized实现原理

  • 在JVM中,同步的实现是通过监视器锁的进入的退出实现的,要么显示通过monitorentermonitorexit指令实现的,要么隐示的通过方法调用和返回指令实现。
  • 对于Java代码来说,或许最常用的同步实现就是同步方法。其中同步代码块是通过使用monitorentermonitorexit实现的,而同步方法却是使用ACC_SYNCHRONIZED标记符隐示的实现,原理是通过方法调用指令检查该方法在常量池中是否包含ACC_SYNCHRONIZED标记符。
同步代码块实现原理
monitor监视器
  • 每个对象都有一个监视器,在同步代码块中,JVM通过monitorentermonitorexit指令实现同步锁的获取和释放功能。
  • 当一个线程获取同步锁时,即是通过获取monitor监视器而等价为获取到锁。
  • monitor的实现类似于操作系统中的管程。
monitorenter指令

每个对象都有一个监视器。当该监视器被占用时即是锁定状态(或者说获取监视器即是获得同步锁)。线程执行monitorenter指令时会尝试获取监视器的所有权,过程如下:

  • 若该监视器的进入次数为0,则该线程进入监视器并将进入次数设置为1,此时该线程即为该监视器的所有者。
  • 若线程已占有该监视器并重入,则进入次数+1。
  • 若其他线程已经占有该监视器,则线程会被阻塞直到监视器的进入次数为零,之后线程间会竞争获取该监视器的所有权。
  • 只有首先获得锁的线程才能允许继续获取多个锁。
monitorexit指令

执行monitorexit指令将遵循以下步骤:

  • 执行monitorexit指令的线程必须是对象实例所对应的监视器的所有者。
  • 指令执行时,线程会先将进入次数-1,若-1之后进入次数变为0.则线程退出监视器(即释放锁)
  • 其他阻塞在该监视器的线程可以重新竞争该监视器的所有权。
小结
  • 在同步代码块中,JVM通过monitorentermonitorexit指令实现同步锁的获取和释放功能。
  • monitorenter指令是在编译后插入到同步代码块的开始位置。
  • monitorexit指令是插入到方法结束处和异常处。
  • JVM要保证每个monitorenter必须有对应的monitorexit与之配对。
  • 任何对象都有一个monitor与之关联,当且一个monitor被持有后,它将处于锁定状态。
  • 线程执行monitorenter指令时,将会尝试获取对象所对应的monitor的所有权,即尝试获取对象的锁。
  • 线程执行monitorexit指令时,将会将进入次数-1直到变成0释放监视器。
  • 同一时刻只有一个线程能够成功,其他失败的线程会被阻塞,并放入到同步队列中,进入BLOCKED状态。
同步方法同步原理
  • 区别在于同步代码块的监视器实现,同步方法通过 ACC_SYNCHRONIZED标记符隐示的实现。
  • 原理是通过方法调用指令检查该方法在常量池中是否包含ACC_SYNCHRONIZED标记符,如果有,JVM要求线程在调用之前请求锁。

参考文章:并发番@Synchronized一文通(1.8版)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值