今天阅读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. 写个自动下载安装Ant的shell脚本【二】

    #!/bin/bash ####################################################### file name: install_ant.sh# # fun ...

  2. bzoj 1051: [HAOI2006]受欢迎的牛 tarjan缩点

    1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2092  Solved: 1096[Submit][Sta ...

  3. 【HTTP】HTTP access control (CORS)

    https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS Cross-site HTTP requests are H ...

  4. 解压Windows的install.wim文件

    转自无需软件,解压Win8/Win8.1的install.wim文件 一.检查镜像版本: 镜像中包含多个版本,需要确认自己需要的版本,我的镜像路径是"F:\win8.1\sources\in ...

  5. 2016 年开发者应该掌握的十个 Postgres 技巧

    [编者按]作为一款开源的对象-关系数据库,Postgres 一直得到许多开发者喜爱.近日,Postgres 正式发布了9.5版本,该版本进行了大量的修复和功能改进.而本文将分享10个 Postgres ...

  6. Palindrome

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

  7. MonkeyRunner 连续两次点击报“Error sending touch event”

    最近用monkeyrunner做自动化测试,遇到连续两次点击,第二次点击就会报错“Error sending touch event”. 具体做法如下: device.touch(234,112, ' ...

  8. git 添加忽略文件

    使用github for windows客户端添加.gitignore文件:   如下图所示,在github客户端可以看到未提交的更改列表 随便选中一个文件,右链,选择ignore file. 然后会 ...

  9. lambda -- Java 8 find first element by predicate

        Java 8 find first element by predicate up vote6down votefavorite I've just started playing with ...

  10. 杂项(最小表示法):HZOI 2015 Glass Beads

    [题目描述] 给定长度为n(n<=300000)的循环同构的字符串,定义最小表示为该字符串的字典序最小的同构表示,请输出这个表示. [输入格式] 第一行是串的长度,第二行是字符串. [输出格式] ...