synchornized实现原理
2024-08-28 19:58:05
synchronized是基于Monitor来实现同步的。
Monitor 的工作机理:
- 线程进入同步方法中。
- 为了继续执行临界区代码,线程必须获取 Monitor 锁。如果获取锁成功,将成为该监视者对象的拥有者。任一时刻内,监视者对象只属于一个活动线程(The Owner)
- 拥有监视者对象的线程可以调用 wait() 进入等待集合(Wait Set),同时释放监视锁,进入等待状态。
- 其他线程调用 notify() / notifyAll() 接口唤醒等待集合中的线程,这些等待的线程需要重新获取监视锁后才能执行 wait() 之后的代码。
- 同步方法执行完毕了,线程退出临界区,并释放监视锁。
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。
最新文章
- Design2:数据层次结构建模之二
- C++_STL
- bootstrap-fileupload-上传文件控件
- 利用 ffmpeg + ImageMagick + 批处理 生成高品质gif动画
- ORACLE 总结
- IOKit找不到问题定义
- bullet HashMap 内存紧密的哈希表
- 『软件介绍』SQLServer2008 基本操作
- 小米路由器mini如何设置外网访问wan网站的方法
- linux加入windows域之完美方案(转载)
- Java异常类(Throwable)
- hbase完全分布式安装
- Angular: 执行ng lint后如何快速修改错误
- PAT 乙级 1086 就不告诉你 (15 分)
- Maven install报MojoFailureException
- Memory Translation and Segmentation.内存地址转换与分段
- DLL接口的实现(虚函数)
- angular ui.router 路由传参数
- STM32 HAL库学习系列第2篇 GPIO配置
- ajax实现json循环输出结果