java中synchronized关键字的实现
来源:互联网 发布:mysql数据库的触发器 编辑:程序博客网 时间:2024/06/04 20:45
java中synchronized关键字的实现说明:java中的同步(synchronized)是基于进入monitor对象和退出monitor对象来实现的,无论是显式同步还是隐式同步。synchronized语句块:1)代码编译后,从生成的class文件中可以看到:同步块的入口位置和出口位置(方法结束处和异常处)分别插入了monitorenter字节码指令和monitorexit字节码指令,故同步代码块属于显示同步。2)线程执行到monitorenter指令时,尝试获取对象的锁。synchronized方法:1)JVM从Class文件中的方法结构(method_info)中的 ACC_SYNCHRONIZED 访问标志区分一个方法是否为同步方法,故同步方法属于隐式同步。2)当方法调用时,调用指令会检查方法的ACC_SYNCHRONIZED访问标志是否被设置,如果设置了,执行线程将先持有monitor,然后再执行方法,最后在方法完成时释放monitor。3)在方法执行期间,其它线程无法获取该monitor。4)如果一个同步方法执行期间抛出了异常,并且在方法内部无法处理此异常,那这个同步方法所持有的monitor将在异常抛到同步方法之外时自动释放。method_info 结构格式如下(java虚拟机规范中的摘录):method_info {u2 access_flags;// 用于定义当前方法的访问权限和基本属性的标志u2 name_index;u2 descriptor_index;u2 attributes_count;attribute_info attributes[attributes_count];}method_info结构中访问标记(access_flags)的取值:标记名值说明ACC_PUBLIC0x0001public,方法可以从包外访问ACC_PRIVATE0x0002 private,方法只能本类中访问ACC_PROTECTED0x0004 protected,方法在自身和子类可以访问ACC_STATIC0x0008 static,静态方法ACC_FINAL0x0010 final,方法不能被重写ACC_SYNCHRONIZED0x0020 synchronized,方法由monitor同步...获取锁和释放锁的内存原语:当线程获取锁时,JMM会把该线程对应的本地内存置为无效。从而使得被monitor保护的临界区代码必须从主内存中读取共享变量。当线程释放锁时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中即:1将本地内存中的数据设置为无效,2从主内存中将数据复制到本地内存中,3在本地内存中进行操作,4操作完成后将本地内存中的数据刷新到主内存中。整体看起来就像是直接在主内存中操作一样。synchronized的可重入性:1)当一个线程再次请求自己持有对象锁的临界资源时,这种情况属于重入锁,请求将会成功。2)由于synchronized是基于monitor实现的,故每次重入,monitor中的计数器仍会加1。深入理解monitor:1)从java的视角看synchronizedsynchronized使用的锁对象(monitor)存储在java对象头中。monitor对象:1)每个java对象都拥有一个Monitor锁(别问我为什么,虚拟机就是这样设计的)。2)当一个monitor被持有后,它将处于锁定状态。2)从C++源码(虚拟机的实现)看synchronized (参考:https://www.cnblogs.com/dennyzhangdd/p/6734638.html) oopDesc ---> markOopDesc monitor()方法 --> ObjectMonitor 即 monitor -> monitor enter、monitor exit1)openjdk\hotspot\src\share\vm\oops\oop.hpp下的oopDesc类是JVM对象的顶级基类,故每个object都包含markOop。class oopDesc {friend class VMStructs;private:volatile markOop _mark;//标记字段(Mark Word)union _metadata {Klass* _klass;//对象类型元数据的指针narrowKlass _compressed_klass;} _metadata;// Fast access to barrier set. Must be initialized.static BarrierSet* _bs;public:markOop mark() const { return _mark; }markOop* mark_addr() const { return (markOop*) &_mark; }void set_mark(volatile markOop m) { _mark = m; }void release_set_mark(markOop m);markOop cas_set_mark(markOop new_mark, markOop old_mark);// Used only to re-initialize the mark word (e.g., of promoted// objects during a GC) -- requires a valid klass pointervoid init_mark();Klass* klass() const;Klass* klass_or_null() const volatile;Klass** klass_addr();narrowKlass* compressed_klass_addr();....省略...}2)markOopDesc继承自oopDesc,并拓展了自己的方法monitor(),该方法返回一个ObjectMonitor*对象指针。ObjectMonitor* monitor() const {assert(has_monitor(), "check");// Use xor instead of &~ to provide one extra tag-bit check.return (ObjectMonitor*) (value() ^ monitor_value);//-------------- 补充 ---------------------//value()的实现: uintptr_t value() const { return (uintptr_t) this; }////monitor_value的实现://enum {//locked_value = 0,//00偏向锁 //unlocked_value = 1,//01无锁//monitor_value = 2,//10监视器锁,又叫重量级锁//marked_value = 3,//11GC标记//biased_lock_pattern = 5 //101偏向锁//};//-------------- 补充 ---------------------}3)在HotSpot虚拟机中,采用ObjectMonitor类来实现monitor。openjdk\hotspot\src\share\vm\runtime\objectMonitor.hpp源码如下:ObjectMonitor() {_header = NULL;//markOop对象头_count = 0;_waiters = 0,//等待线程数_recursions = 0;//重入次数_object = NULL;_owner = NULL;//指向获得ObjectMonitor对象的线程或基础锁_WaitSet = NULL;//处于wait状态的线程,会被加入到wait set;_WaitSetLock = 0 ;_Responsible = NULL ;_succ = NULL ;_cxq = NULL ;FreeNext = NULL ;_EntryList = NULL ;//处于等待锁block状态的线程,会被加入到entry set;_SpinFreq = 0 ;_SpinClock = 0 ;OwnerIsThread = 0 ;// _owner is (Thread *) vs SP/BasicLock_previous_owner_tid = 0;// 监视器前一个拥有者线程的ID}
阅读全文
0 0
- java中synchronized关键字的实现
- Java中Synchronized关键字
- Java中synchronized关键字
- java同步关键字Synchronized 的实现原理
- Java中 synchronized 关键字的用法
- Java中synchronized关键字锁定的内容
- Java中synchronized关键字锁定的内容
- java多线程中synchronized关键字的用法
- java多线程中synchronized关键字的用法
- Java中synchronized关键字的简单理解
- java 中synchronized关键字的用法
- Java中synchronized关键字锁定的内容
- java中volatile、synchronized 关键字的含义
- Java中synchronized关键字的使用
- java中synchronized关键字的用法
- java中synchronized关键字的认识&记录
- java中volatile、synchronized关键字的含义
- java中synchronized关键字的用法
- Ubuntu环境下载Python库PIL(这个库有毒!!!)
- UOJ261 NOIP2016 day1 T2 天天爱跑步 (lca + 桶 )
- 深度学习进阶(三)--BackPropagation算法的影响因素(补充昨天的博客更新)
- Android mk 引用 jar 包、so 库、aar 包,系统签名
- LeetCode-110. Balanced Binary Tree
- java中synchronized关键字的实现
- Hello_Java
- Java Activiti(4)--查询历史任务数据等信息
- Codeforces Problem 333D. Characteristics of Rectangles
- servlet 杂谈
- 亚马逊:您的评论无法发布。 (靠)
- 【c++】关于继承
- svn,maven工程注意事项
- (M)Dynamic Programming:523. Continuous Subarray Sum