Java 多线程性能调优之Synchronized

并发编程中,多个线程共享一个资源时,我们得考虑维护这个资源的原子性,确保

一个线程在操作共享资源时,同时不会被另一个线程所操作

JDK1.6 版本之前,Synchronized被称之为重量级锁,为什么呢?因为Synchronized 是

基于底层操作系统的 Mutex Lock 实现的,每次获取和释放锁操作都会带来用户态和内核

态的切换,cpu必须花时间和空间保存当时的操作现场从而增加系统性能开销,在锁竞争

激烈的情况下,Synchronized 同步锁在性能上就表现得很不好。1.6之后,Synchronized

经过多种优化实现了性能的大幅提升,接下来我们就看看Synchronized做了哪些优化,

首先介绍一下Synchronized锁同步的原理

Synchronized同步原理

Synchronized可以用来修饰方法和代码块

修饰代码块的情况下,我们反编译打印出字节码文件看看


Synchronized 在修饰同步代码块时,是由 monitorenter 和 monitorexit 指令来实现同步的。

进入 monitorenter 指令后,线程将持有 Monitor 对象,退出 monitorenter 指令后,线程将

释放该Monitor对象

修饰方法时候:


当 Synchronized 修饰同步方法时,并没有发现 monitorenter 和 monitorexit 指令,

而是出现了一个 ACC_SYNCHRONIZED 标志。

流程是这样的:JVM用ACC_SYNCHRONIZED这个标志来判断一个方法是不是同步方法,

当调用了一个方法的时候,会先判断这个方法是否有同步标志ACC_SYNCHRONIZED ,

有的话执行的线程先持有monitor对象,然后开始执行方法,执行完再释放monitor对象。

JVM的同步是基于进入和退出管程Monitor实现的

管程是由局部于自己的若干公共变量及其说明和所有访问这些公共变量的过程所组成的

软件模块

每个对象都有一个monitor,monitor和对象一起被创建和销毁

Monitor 是由 ObjectMonitor 实现,而 ObjectMonitor 是由 C++ 的 ObjectMonitor.hpp实现


一开始,访问同步代码的线程都会被加入到EntryList中,处于block状态,然后去竞争

monitor,Monitor 是依靠底层操作系统的Mutex Lock来实现互斥的,线程申请 Mutex 成功,

则持有该 Mutex,其它线程将无法获取到该 Mutex,如果线程调用wait()方法,那么就会放弃

Mutex,从而进入WaitSet中等待唤醒,因为monitor是依赖cpu实现的,存在操作系统内核态

和用户态之间的切换,有额外的性能开销

Java 对象头

jdk1.6开始,对象实例在jvm堆里面,被分成了三部分,对象头、实例数据和对齐填充,

对象头又由mark word 、指向类的指针和数组长度三部分组成。

mark word记录了对象和锁的相关信息,在64位的jvm中,mark word的长度是64bit

锁升级

Synchronized相较于之前的版本,做的优化便是锁升级,便是依赖markword中锁的信息

而完成锁的升级,由最开始的无锁变成偏向锁、轻量级锁和最后的重量级锁。我们接下来

看看Synchronized是怎么做的

偏向锁

1.6之前,我们获取锁需要进入monitor,释放锁需要退出monitor,其中的系统内核和用户态

的切换便是性能开销所在,我们是想避免这种切换带来的性能开销

在一些场景下,去获取锁的线程可能同一个线程,既然是同一个线程,我们便没必要依赖

monitor而产生性能开销,偏向锁就是去这个对象的mark word里面看偏向锁的线程id是不是

自己,是的话,就不去竞争monitor了,当对象被当作同步锁并且被一个线程持有之后,

锁标志位保持不变,然后把 是否是偏向锁  置为1,然后把线程id记录下来,这样便表示

这个对象此时是一个偏向锁,下次有线程来获取自己的时候,如果还是上次的线程,那么

就直接持有这个锁,如果不是,那么偏向锁就会被撤销,撤销需要等待stw安全点,锁标志

位置为00表示轻量锁,完成锁的一次升级。

轻量级锁

当另一个线程来竞争这个锁的时候,发现是个偏向锁并且mark word记录的线程id不是自己,

就会通过CAS尝试获取这个锁,如果成功,就把线程id改成自己的id,如果失败,那么就升级

为轻量级锁,锁标志位更改为00

自旋锁和重量级锁

另一个线程来竞争锁的时候,线程通过CAS尝试获取锁,假如CAS一次失败后便不再

尝试,从而线程被挂起阻塞,通常情况下,锁的持有时间都不会太久,通过自旋的方式

不断的去尝试获取锁,以避免线程的挂起阻塞,自旋之后还是失败的话,那么锁升级为

重量级锁,锁标志位更改为10,就变成我们最开始说的通过进入和退出monitor竞争锁

多线程调优

当我们已知场景是高并发场景,必然会有大量线程竞争同一资源,那么我们可以关闭偏向锁

,省去等待stw偏向锁撤销的开销,-XX:-UseBiasedLocking

或者直接-XX:+UseHeavyMonitors 设置成为重量级锁

在锁竞争不激烈且锁占有时间不长的情况下,自旋锁可以提高性能,反之,竞争激烈的情况

或者持有时间较长的情况下,自旋更多只是导致大量线程重试占用cpu资源,可以通过

-XX:-UseSpinning关闭自旋锁

JIT编译器通过逃逸分析,如果判断出同步代码使用的对象并不会被发布到其他线程,

那么便不会生成Synchronized的相关机器码,称为锁消除

如果发现多个相邻同步块使用的是同一对象,便会在编译阶段把这几个同步块合并成一个大

的同步块,避免线程反复的申请释放同一个对象

在我们编码层面,我们可以通过锁粒度的减小从而提高并发度,例如ConcurrentHashMap,

从整个数组的粒度变为分段锁的segment粒度,从而提高了并发度

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容