Synchronized锁在Spring事宜打点下,为啥还线程不安详?
副问题[/!--empirenews.page--]
媒介只有秃顶才气变强。 文本已收录至我的GitHub客栈,接待Star:https://github.com/ZhongFuCheng3y/3y 伴侣问了我一个技能的题目(伴侣其实是勤学,服气!) 该题目来历知乎(synchronized锁题目): https://www.zhihu.com/question/277812143 开启10000个线程,每个线程给员工表的money字段【初始值是0】加1,没有行使气馁锁和乐观锁,可是在营业层要领上加了synchronized要害字,题目是代码执行完毕后数据库中的money 字段不是10000,而是小于10000 题目出在那边? Service层代码: SQL代码(没有加气馁/乐观锁): 用1000个线程跑代码: 简朴来说:多线程跑一个行使synchronized要害字修饰的要领,要领内操纵的是数据库,按正常逻辑应该最终的值是1000,但颠末多次测试,功效是低于1000。这是为什么呢? 一、我的思索既然测试出来的功效是低于1000,那声名这段代码不是线程安详的。不是线程安详的,那题目呈此刻哪呢?众所周知,synchronized要领可以或许担保所修饰的代码块、要领担保有序性、原子性、可见性。 讲原理,以上的代码跑起来,题目中Service层的increaseMoney()是有序的、原子的、可见的,以是断定跟synchronized应该不要紧。 (参考我之前写过的synchronize锁条记:Java锁机制相识一下) 既然Java层面上找不到缘故起因,那说明一下数据库层面的吧(由于要领内操纵的是数据库)。在increaseMoney()要领前加了@Transcational注解,声名这个要领是带有事宜的。事宜能担保同组的SQL要么同时乐成,要么同时失败。讲原理,假如没有报错的话,应该每个线程都对money值举办+1。从理论上来说,功效应该是1000的才对。 (参考我之前写过的Spring事宜:一文带你看懂Spring事宜!) 按照上面的说明,我猜疑是提问者没测试好(hhhh,逃),于是我也跑去测试了一下,发明是以提问者的方法来行使是真的有题目。 起首贴一下我的测试代码:
简朴地打印了每次拿到的employee值,而且拿到了SQL执行的次序,如下(贴出小部门): 从打印的环境我们可以得出:多线程环境下并没有串行执行addEmployee()要领。这就导致对统一个值做一再的修改,以是最终的数值比1000要少。 二、图解呈现的缘故起因发明并不是同步执行的,于是我就猜疑synchronized要害字和Spring必定有点斗嘴。于是按照这两个要害字搜了一下,找到了题目地址。 (编辑:河北网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |