- 1、本文档共13页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Java中 synchronized 关键字的用法
打个比方:一个object就像一个大房子,大门永远打开。房子里有很多房间(也就是方
法)。这些房间有上锁的(synchronized 方法),和不上锁之分(普通方法)。房门口放着一把钥
匙(key),这把钥匙可以打开所有上锁的房间。另外我把所有想调用该对象方法的线程比喻
成想进入这房子某个房间的人。所有的东西就这么多了,下面我们看看这些东西之间如何作
用的。 在此我们先来明确一下我们的前提条件。该对象至少有一个synchronized 方法,
否则这个key 还有啥意义。当然也就不会有我们的这个主题了。
一个人想进入某间上了锁的房间,他来到房子门口,看见钥匙在那儿(说明暂时还没有
其他人要使用上锁的房间)。于是他走上去拿到了钥匙,并且按照自己的计划使用那些房间。
注意一点,他每次使用完一次上锁的房间后会马上把钥匙还回去。即使他要连续使用两间上
锁的房间,中间他也要把钥匙还回去,再取回来。
因此,普通情况下钥匙的使用原则是:“随用随借,用完即还。”
这时其他人可以不受限制的使用那些不上锁的房间,一个人用一间可以,两个人用一间
也可以,没限制。但是如果当某个人想要进入上锁的房间,他就要跑到大门口去看看了。有
钥匙当然拿了就走,没有的话,就只能等了。
要是很多人在等这把钥匙,等钥匙还回来以后,谁会优先得到钥匙?Not guaranteed。
象前面例子里那个想连续使用两个上锁房间的家伙,他中间还钥匙的时候如果还有其他人在
等钥匙,那么没有任何保证这家伙能再次拿到。 (JAVA 规范在很多地方都明确说明不保证,
象Thread.sleep()休息后多久会返回运行,相同优先权的线程那个首先被执行,当要访问对
象的锁被释放后处于等待池的多个线程哪个会优先得到,等等。我想最终的决定权是在
JVM,之所以不保证,就是因为JVM 在做出上述决定的时候,绝不是简简单单根据一个条
件来做出判断,而是根据很多条。而由于判断条件太多,如果说出来可能会影响JAVA 的推
广,也可能是因为知识产权保护的原因吧。SUN 给了个不保证就混过去了。无可厚非。但
我相信这些不确定,并非完全不确定。因为计算机这东西本身就是按指令运行的。即使看起
来很随机的现象,其实都是有规律可寻。学过计算机的都知道,计算机里随机数的学名是伪
随机数,是人运用一定的方法写出来的,看上去随机罢了。另外,或许是因为要想弄的确定
太费事,也没多大意义,所以不确定就不确定了吧。)
再来看看同步代码块。和同步方法有小小的不同。
1.从尺寸上讲,同步代码块比同步方法小。你可以把同步代码块看成是没上锁房间里的
一块用带锁的屏风隔开的空间。
2.同步代码块还可以人为的指定获得某个其它对象的key。就像是指定用哪一把钥匙才
能开这个屏风的锁,你可以用本房的钥匙;你也可以指定用另一个房子的钥匙才能开,这样
的话,你要跑到另一栋房子那儿把那个钥匙拿来,并用那个房子的钥匙来打开这个房子的带
锁的屏风。
记住你获得的那另一栋房子的钥匙,并不影响其他人进入那栋房子没有锁的房间。
为什么要使用同步代码块呢?我想应该是这样的:首先对程序来讲同步的部分很影响运
行效率,而一个方法通常是先创建一些局部变量,再对这些变量做一些操作,如运算,显示
等等;而同步所覆盖的代码越多,对效率的影响就越严重。因此我们通常尽量缩小其影响范
围。如何做?同步代码块。我们只把一个方法中该同步的地方同步,比如运算。
另外,同步代码块可以指定钥匙这一特点有个额外的好处,是可以在一定时期内霸占某
个对象的key。还记得前面说过普通情况下钥匙的使用原则吗。现在不是普通情况了。你所
取得的那把钥匙不是永远不还,而是在退出同步代码块时才还。
还用前面那个想连续用两个上锁房间的家伙打比方。怎样才能在用完一间以后,继续使
用另一间呢。用同步代码块吧。先创建另外一个线程,做一个同步代码块,把那个代码块的
锁指向这个房子的钥匙。然后启动那个线程。只要你能在进入那个代码块时抓到这房子的钥
匙,你就可以一直保留到退出那个代码块。也就是说你甚至可以对本房内所有上锁的房间遍
历,甚至再sleep(10*60*1000),而房门口却还有1000个线程在等这把钥匙呢。很过瘾吧。
在此对sleep()方法和钥匙的关联性讲一下。一个线程在拿到key后,且没有完成同步
的内容时,如果被强制sleep()了,那key还一直在它那儿。直到它再次运行,做完所有同
步内容,才会归还key。记住,那家伙只是干活干累了,去休息一下,他并没干完他要干的
事。为了避免别人进入那个房间把里面
文档评论(0)