网站大量收购独家精品文档,联系QQ:2885784924

Java 慎用方法级别的synchronized关键字.pdf

Java 慎用方法级别的synchronized关键字.pdf

  1. 1、本文档共4页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Java 慎用方法级别的synchronized关键字

Java 慎用方法级别的synchronized关键字 2013-01-23 • 并发、技术 • 1 条评论 • j iacheo • 8,64 1 阅读 为什么要这么说呢 , 因为笔者被这个坑过 (其实是自己坑自己)╮(╯_ ╰) ╭ 先看一段synchronized 的详解 : synchronized 是 java语言的关键字 ,当它用来修饰一个方法或者一个代码块的时候 ,能够保证在同一 时刻最多只有一个线程执行该段代码。 一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时 ,一个时间内只 能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。 二、然而 ,当一个线程访问object的一个synchronized(this)同步代码块时 ,另一个线程仍然可以访问 该object中的非synchronized(this)同步代码块。 三、尤其关键的是 ,当一个线程访问object的一个synchronized(this)同步代码块时 ,其他线程对object 中所有其它synchronized(this)同步代码块的访问将被阻塞。 四、第三个例子同样适用其它同步代码块。也就是说 ,当一个线程访问object的一个 synchronized(this)同步代码块时 ,它就获得了这个object的对象锁。结果 ,其它线程对该object对象所 有同步代码部分的访问都被暂时阻塞。 五、以上规则对其它对象锁同样适用. 简单来说, synchronized就是为当前的线程声明一个锁, 拥有这个锁的线程可以执行区块里面的指令, 其 他的线程只能等待获取锁, 然后才能相同的操作. 这个很好用, 但是笔者遇到另一种比较奇葩的情况. 1. 在同一类中 , 有两个方法是用了synchronized关键字声明 2. 在执行完其中一个方法的时候 , 需要等待另一个方法 (异步线程回调 )也执行完 , 所以用了一个 countDownLatch来做等待 3. 代码解构如下 : synchronized void a(){ countDownLatch = new CountDownLatch(1); // do someing countDownLatch.await(); } synchronized void b(){ countDownLatch.countDown(); } 其中 a方法由主线程执行, b方法由异步线程执行后回调 执行结果是: 主线程执行 a方法后开始卡住, 不再往下做, 任你等多久都没用. 这是一个很经典的死锁问题 a等待b执行, 其实不要看b是回调的, b也在等待a执行. 为什么呢? synchronized 起了作用. 一般来说, 我们要synchronized一段代码块的时候, 我们需要使用一个共享变量来锁住, 比如: byte[] mutex = new byte[0]; void a1(){ synchronized(mutex){ //dosomething } } void b1(){ synchronized(mutex){ // dosomething } } 如果把a方法和b方法的内容分别迁移到 a1和b1 方法的synchronized块里面, 就很好理解了. a1执行完后会间接等待(countDownLatch)b1方法执行 然而由于 a1 中的mutex并没有释放, 就开始等待b1了, 这时候, 即使是异步的回调b1方法, 由于需要等 待mutex释放锁, 所以b方法并不会执行 于是就引起了死锁 而这里的synchronized关键字放在方法前面, 起的作用就是一样的. 只是java语言帮你隐去了mutex的声 明和使用而已. 同一个对象中的synchronized 方法用到的mutex是相同的, 所以即使是异步回调, 也会引 起死锁, 所以要注意这个问题. 这种级别的错误是属于synchronized关键字使用不当. 不要乱用, 而且要 用对. 那么这样的 隐形的mutex 对象究竟是 什么呢? 很容易想到的就是 实例本身. 因为这样就不用去定义新的对象了做锁了. 为了证明这个设想, 可以写一 段程序来证明. 思路很简单, 定义一个类

文档评论(0)

ljxmax118 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档