关于Synchronized关键字的疑问
来源:9-1 死锁
![](http://img1.sycdn.imooc.com/user/5a45a66e0001686705400594-100-100.jpg)
寒暄丶
2019-01-09
昨天在工作中碰到这么一种情况,用户每个月消费1000返100,在每个月初结算并在app上弹窗供用户点击领取,这里因为涉及并发问题所以考虑到可用的操作,觉得synchronized(项目jdk1.7)比较快捷有效。
当时采用synchronized锁住的是在该类中创建的静态对象,但是实测发现,只要疯狂点领取按钮/Jmeter 0秒多线程压测,还是会发生多次领取到的情况!!
1.这里就产生一个问题,这是否可以证明死锁这个例子的synchronized选择锁住的静态对象但还是线程不安全的呢?
于是对synchronized关键字锁住的东西再次感到有些迷茫,早上在网上找到一篇简书是这么一个表格:
和这么一段话:
2.上述陈述的结论我是这么理解的:既然用到了synchronized,就应该保证锁住的东西是类对象,否则都是线程不安全的。
但是这个想法我用synchronized修饰了方法又测试发现不会出现多次领取的情况,而且用简书文章末尾的方法就是synchronized修饰类对象依然会出现多次领取的情况!!!真的感觉很困扰很混乱
麻烦老师帮忙分析解答一下,多谢老师!!!!!
(这是此篇简书的链接https://www.jianshu.com/p/d53bf830fa09 侵删)
2回答
-
你好,这样理解确实有点问题,理论上使用synchronized的话,同步的具体范围是开发自己选的,核心是锁最关键的共享资源,而且要尽可能小。有一点需要明确,许多可以辅助做到线程安全的类,使用不当的话,也会造成线程不安全,比如课程里演示的vector删除
synchronized支持多种类型的同步,每一种同步都明确了自己的锁范围,这个需要开发人员选择最合适的,可以锁类对象也可以锁实例对象,虽然锁类对象可以完全保证线程安全,但不代表只能使用这种,因为代价最大,我们实际中要尽可能的减小锁的程度。但是如果锁实例对象解决不了根本问题,那么锁类对象也是必须的。
这两种锁操作本身都是线程安全的,而不能因为错用就说锁对象实例是线程不安全的,这只能说明那种场合不适合锁实例对象,因为synchronized确实已经锁住了实例对象。072019-01-09 -
寒暄丶
提问者
2019-01-09
用了ConcurrentHashMap缓存 + 延时线程池(定时清缓存) + synchronized关键字修饰静态Object的方式暂时解决了这个问题 果然理论还是得自己实践才能慢慢来体会吧.. 还是自己没理清,还是很感谢有老师的知道~
00
相似问题