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作用的范围不一样而已。

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




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



可以从结果看到,synchronized已经没有起到多线程同步安全的作用了,因为synchronized锁定的对象为s,每次调用run局部方法的时候都会重新创建一个实例对象s,锁定的不是同一个对象,不是共享的资源,所以就不起作用了,即使syncThread实例对象只有一个也是没有作用的,因为锁定的对象并不是它。接下来,再稍微做一下改动。



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



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



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

接下来,在贴一个过程:




可以看到,即使两个线程one使用syncThread1,two使用syncThread2,synchronized也能起到控制多线程同步安全的作用,因为count是静态的单一的共享资源,synchronized锁定的就是它,跟SyncThread有多少个实例对象是没有任何关系的。这里只是再次强调一下synchronized只跟它锁定的对象是否单一有关系,如果是单一对象,那就谁先抢到该对象资源,谁就先执行,另外的线程只能等待。

大概就是这样了,以上纯属个人愚见,老了,写下来也是为了自己方便记得,有兴趣可以看下。

猜你喜欢

转载自blog.csdn.net/qq_30021219/article/details/80037725