synchronized是基于Monitor来实现同步的。

Monitor 的工作机理:

  1. 线程进入同步方法中。
  2. 为了继续执行临界区代码,线程必须获取 Monitor 锁。如果获取锁成功,将成为该监视者对象的拥有者。任一时刻内,监视者对象只属于一个活动线程(The Owner)
  3. 拥有监视者对象的线程可以调用 wait() 进入等待集合(Wait Set),同时释放监视锁,进入等待状态。
  4. 其他线程调用 notify() / notifyAll() 接口唤醒等待集合中的线程,这些等待的线程需要重新获取监视锁后才能执行 wait() 之后的代码。
  5. 同步方法执行完毕了,线程退出临界区,并释放监视锁。

synchronized具体实现

同步方法使用ACC_SYNCHRONIZED标记符隐式的实现。

同步代码块采用monitorenter、monitorexit指令显式的实现。

ACC_SYNCHRONIZED

方法级别的同步是隐式的,它实现在方法调用和返回操作之中。虚拟机可以从方法常量池中的方法表结构(method_info structure)中的 ACC_SYNCHRONIZED 访问标志区分一个方法是否是同步方法。当调用方法时,调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否设置,如果设置了,执行线程先持有同步锁,然后执行方法,最后在方法完成时释放锁。

monitorenter

每一个对象都有一个monitor,一个monitor只能被一个线程拥有。当一个线程执行到monitorenter指令时会尝试获取相应对象的monitor,获取规则如下:

  • 如果monitor的进入数为0,则该线程可以进入monitor,并将monitor进入数设置为1,该线程即为monitor的拥有者。
  • 如果当前线程已经拥有该monitor,只是重新进入,则进入monitor的进入数加1,所以synchronized关键字实现的锁是可重入的锁。
  • 如果monitor已被其他线程拥有,则当前线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获取monitor。

monitorexit

只有拥有相应对象的monitor的线程才能执行monitorexit指令。每执行一次该指令monitor进入数减1,当进入数为0时当前线程释放monitor,此时其他阻塞的线程将可以尝试获取该monitor。

synchornized实现原理的更多相关文章

  1. 02 如何创建线程 线程并发与synchornized

    所有程序运行结果 请自行得出 创建线程方式一:继承Thread类 步骤: 1,定义一个类继承Thread类. 2,覆盖Thread类中的run方法. 3,直接创建Thread的子类对象创建线程. 4, ...

  2. 关于Synchornized,Lock,AtomicBoolean和volatile的区别介绍

    1.  volatile 变量可以被看作是一种 "程度较轻的 synchronized". 2.  Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的 ...

  3. 并发编程原理学习:synchronized关键字

    概述 关键字synchronized可以修饰方法或者以同步代码块的形式来进行使用,它主要确保多个线程在同一时刻只能有一个线程处于方法或者同步块中,它保证了线程对变量访问的可见性和排他性. 同步代码块 ...

  4. 奇异值分解(SVD)原理与在降维中的应用

    奇异值分解(Singular Value Decomposition,以下简称SVD)是在机器学习领域广泛应用的算法,它不光可以用于降维算法中的特征分解,还可以用于推荐系统,以及自然语言处理等领域.是 ...

  5. node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理

    一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...

  6. 线性判别分析LDA原理总结

    在主成分分析(PCA)原理总结中,我们对降维算法PCA做了总结.这里我们就对另外一种经典的降维方法线性判别分析(Linear Discriminant Analysis, 以下简称LDA)做一个总结. ...

  7. [原] KVM 虚拟化原理探究(1)— overview

    KVM 虚拟化原理探究- overview 标签(空格分隔): KVM 写在前面的话 本文不介绍kvm和qemu的基本安装操作,希望读者具有一定的KVM实践经验.同时希望借此系列博客,能够对KVM底层 ...

  8. H5单页面手势滑屏切换原理

    H5单页面手势滑屏切换是采用HTML5 触摸事件(Touch) 和 CSS3动画(Transform,Transition)来实现的,效果图如下所示,本文简单说一下其实现原理和主要思路. 1.实现原理 ...

  9. .NET Core中间件的注册和管道的构建(1)---- 注册和构建原理

    .NET Core中间件的注册和管道的构建(1)---- 注册和构建原理 0x00 问题的产生 管道是.NET Core中非常关键的一个概念,很多重要的组件都以中间件的形式存在,包括权限管理.会话管理 ...

随机推荐

  1. Python多线程、多进程和协程的实例讲解

    线程.进程和协程是什么 线程.进程和协程的详细概念解释和原理剖析不是本文的重点,本文重点讲述在Python中怎样实际使用这三种东西 参考: 进程.线程.协程之概念理解 进程(Process)是计算机中 ...

  2. java.math.BigDecimal

    package day14; import java.math.BigDecimal; /** * Created by admin on 2018/11/24. * 看程序写结果:结果和我们想的有一 ...

  3. Apache http server linux 安装过程说明

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/sundenskyqq/article/details/24733923 PS:Apache http ...

  4. 面试题5:JS实现从尾到头打印单链表

    单链表,在内存中所占地址是不连续的.所以遍历单链表时:需要从头遍历.而题目要求输出的顺序:从尾到头.也就是说第一个遍历到的节点最后一个输出,而最后一个遍历到的节点第一个输出.这就是典型的“后进先出”, ...

  5. labview 的连接

    https://www.youtube.com/watch?v=AsQ56CmnfEA&list=PLp02wZHiCj4tcot7tPumcOeVR51oqzf6V

  6. CentOS忘记用户名或者密码解决办法

    方法一:如果用户名和密码都忘记了,可以用以下这个方法找回:(和第二种大步骤差不多,需注意3,4步) 1. 在出现grub画面时,用上下键选中你平时启动linux的那一项,然后按e键 2. 再次用上下键 ...

  7. 如何修改opencart的模版适合为mycncart系统使用

    如何修改opencart的模版适合为mycncart系统使用 mycncart跟随opencart的最新代码不断进行升级,并改造和不断加入中国特色的功能,因此opencart的模版均不能够拿来直接套用 ...

  8. 接管radiobutton onclick 事件

    You can nil the OnClick event handler while changing a radiobutton state programmatically: procedure ...

  9. nuget发布自已的程序集

    1.nuget注册并获取apikey 2.下载nuget.exe 3.设置apikey nuget setApiKey <apikey> 4.开发程序集 5.进入.csproj目录生成描述 ...

  10. 自动配置@Resource与@Autowired

    总结自:https://www.cnblogs.com/kuotian/p/8795812.html 试用情形:bean的某个成员变量是另一个bean 如果使用配置: <bean id=&quo ...