今天阅读java.util.concurrent 中 ArrayBlockingQueue 的源码,发现其中有很多下面这行代码

final ReentrantLock lock = this.lock

对此行代码非常疑惑,为什么不直接使用this.lock 呢?为什么要使用局部变量呢?于是使用强大的谷歌搜了一把,发现下面两种答案

1. concurrent包的作者Doug Lea 在邮件当中的回复

It’s ultimately due to the fundamental mismatch between memory models
and OOP 

Just about every method in all of j.u.c adopts the policy of reading fields as locals whenever a value is used more than once.This way you are sure which value applies when.This is not often pretty, but is easier to visually verify.

The surprising case is doing this even for “final” fields.This is because JVMs are not always smart enough to exploit the fine points of the JMM and not reload read final values, as they would otherwise need to do across the volatile accesses entailed in locking. Some JVMs are smarter than they used to be about this, but still not always smart enough.

个人E文不好,java水平有限,难以理解

2. 这样写,一般是因为引用的变量(一般是类的成员变量)是可变的。通过在栈上增加一个变量来引用这个可变域,可以防止在以后的操作中,由于其他的并发修改操作导致这个可变域在多次访问中引用值不一致,从而最终导致数据不一致。

补充一下,性能上的可能优化点:

  • 1、this.lock是类的成员变量,一般都是存到堆上,访问堆上的变量会涉及内存同步的操作(这个建议通过编译后的bytecode进行观察),而将其copy到栈上,然后访问就不存在这个问题了;
  • 在访问堆上的this.lock时,对于多个CPU,可能会存在cache命中的问题,这样必然会导致内存重新load,而copy到栈上,则直接是线程相关的,就不存在这个问题了。

答案2似乎比较容易理解一些,似懂非懂吧,先记录下来。

ArrayBlockingQueue 源码阅读 问题(一)的更多相关文章

  1. java多线程系列(九)---ArrayBlockingQueue源码分析

    java多线程系列(九)---ArrayBlockingQueue源码分析 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 j ...

  2. 《java.util.concurrent 包源码阅读》 结束语

    <java.util.concurrent 包源码阅读>系列文章已经全部写完了.开始的几篇文章是根据自己的读书笔记整理出来的(当时只阅读了部分的源代码),后面的大部分都是一边读源代码,一边 ...

  3. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  4. 【原】FMDB源码阅读(二)

    [原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...

  5. 【原】FMDB源码阅读(一)

    [原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...

  6. 【原】AFNetworking源码阅读(六)

    [原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...

  7. 【原】AFNetworking源码阅读(五)

    [原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...

  8. 【原】AFNetworking源码阅读(四)

    [原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...

  9. 【原】AFNetworking源码阅读(三)

    [原]AFNetworking源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇的话,主要是讲了如何通过构建一个request来生成一个data tas ...

随机推荐

  1. iOS 实现脉冲雷达以及动态增减元素 By Swift-感谢分享

    Swift经过Xcode6 Beta4一版更新后,基本上已经可以作为生产工具了,虽然有一些地方和ObjC比起来要“落后”一些,但也无伤大雅.这里就用Xcode6 Beta4+iOS SDK 8.0开发 ...

  2. (转) 基于Theano的深度学习(Deep Learning)框架Keras学习随笔-01-FAQ

    特别棒的一篇文章,仍不住转一下,留着以后需要时阅读 基于Theano的深度学习(Deep Learning)框架Keras学习随笔-01-FAQ

  3. List Of All Machine Learning Sorted By Citation

    List Of All Machine Learning Sorted By Citation With > 300 citations 2013-10-10 See Citation Anal ...

  4. Windows常见蓝屏故障分析

    转自Windows常见蓝屏故障分析 症状描述: 当您在运行Microsoft Windows 2000/XP/Server 2003.Microsoft Windows Vista/Server 20 ...

  5. Palindrome

    poj3974:http://poj.org/problem?id=3974 题意:求给定长度最长回文串的长度. 题解:直接套manacher,搞定. #include<iostream> ...

  6. 使用expect实现批量操作的自动化

    http://blog.csdn.net/hijk139/article/details/9121345

  7. 启用VSFTPD日志及其解读

    启用vsftpd日志及其解读(转贴)在vsftpd.conf中有如下内容定义了日志的记录方式:# 表明FTP服务器记录上传下载的情况xferlog_enable=YES# 表明将记录的上传下载情况写在 ...

  8. bug修复复盘

    mybatis与数据库交互时,报了莫名其妙的错,日志中显示的Stack Trace中报错的代码行数与IDE中还一致,逐重启tomcat,异常消失. 故障复盘:没有重启tomcat,使用copy命令直接 ...

  9. c++复习基础要点02 虚函数与模板 与static inline是否共存

    1.      虚函数能否定义为模板函数 当一个类有虚函数时,它一定有一个虚表,用来纪录每个虚函数的实际地址.这也就是说这个虚表的大小是在编译期就确定了的.有多少个虚函数,虚表就纪录几个.       ...

  10. SQL in查询报告类型转换失败的3种解决办法

    -- in查询 nvarchar转int 错误 (NodeId 为 int 类型) ) = '3,5,6,' )' SELECT ID , NodeName FROM WF_WorkFlowNode ...