Java中synchronized同步的个人见解

关于synchronized关键字,网上查询了很多的资料,有很多的说法,有的感觉甚至都没有说出个所以然,然后就直接跳过了,有的感觉都没有说到那个可以让人理解的理由,什么类锁,对象锁,全局锁,还有人说问锁定的是对象还是代码块,说的感觉让人很专业化,很复杂,但是还是不明白是怎么一回事,说的不全面,不具体,羞涩难懂。网上的各种说法真的是很多,越看越让我摸不着头脑。

最后还是觉得经过自己的运行测试比较靠谱一点:

synchronized其实锁定的可以是任何资源(对象,基本数据类型变量,类....),关于synchronized(this),synchronized(xx.class),synchronized方法,static synchronized方法,其实都是通过锁定的资源是否是同个资源,谁先抢到这个锁(锁定的资源),谁就先执行synchronized大括号内的这一段代码,关键就在于锁定的资源是否是一样的。跟什么多少个实例,全局锁什么的统统都没有关系。

锁定的对象就比如:

synchronized(this),this就是当前对象,synchronized方法和synchronized(this)代码块是一样的,只不过是synchronized作用的范围不一样而已。

synchronized(xx.class),xx.class就是锁,static synchronized方法和synchronized(xx.class)代码块也是一样的,只是作用的范围不一样而已。

下面贴一下程序运行的代码和结果:

 

synchronized(this),synchronized锁定的this对象,即TicketConsumer实例对象只有一个,两个线程使用的是同一把锁(ticketConsumer对象,锁的HashCode都为:1417180225),所以synchronized能起到控制多线程同步安全的作用。接下来,稍微做一下改动。

 

可以从结果看到,synchronized已经没有起到多线程同步安全的作用了,因为synchronized锁定的对象为str,每次调用run局部方法的时候都会重新创建一个实例对象s,锁定的不是同一个对象,锁的HashCode也一直在变,很明显,所以就不起作用了。接下来,再稍微做一下改动。

 

synchronized能起到控制多线程同步安全的作用,有的人也许会问,str不是每次调用run局部方法的时候也会重新创建吗?这个因为是String类型,和StringBuffer是有区别的,有了解的人就知道,String数据类型是保存在常量池的,重新创建,引用的是常量池的同一个对象,锁的HashCode也一直没变,synchronized锁定的依然是一个共享资源,谁先抢到谁先执行。接下来,再稍微做一下改动。

可以看到,synchronized能起到控制多线程同步安全的作用,之所以可以,是因为每个类都有唯一的字节码,锁定的是同一个资源,同一把锁。至于synchronized修饰方法,就不贴过程了,和同步块是一样的,只是作用的范围不同,synchronized方法就是相当于synchronized(this),static synchronized方法就相当于synchronized(该类.class)。

以上输出结果为true,可以看到,classs和classi的引用值是相等的,引用的是同一个对象。

接下来,再贴一个过程:

 

可以从结果看到,synchronized已经没有起到多线程同步安全的作用了,以Integer类型对象作为锁,并且不断的进行减一,锁的HashCode也一直在变,具体原因参考当Synchronized遇到这玩意儿,有个大坑,要注意!这篇文章,大致原因就是因为减一的操作会创建一个新的Integer类型对象,这时锁就改变了。不过一般正常情况下也不会有人拿这个票数去作为锁。接下来,再稍微做一下改动。

可以从结果看到,synchronized已经没有起到多线程同步安全的作用,我想原因跟上面的也是一样,在强制转换的过程中创建了一个新的Integer类型对象作为锁,锁的HashCode也一直在变。

这里再次强调一下synchronized只跟它锁定的资源有关,谁先抢到该资源,谁就先执行,另外的线程只能等待。无论多少个对象,多少个类,关键在于是否是同一把锁。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值