博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ArrayBlockingQueue 源码阅读 问题(一)
阅读量:4970 次
发布时间:2019-06-12

本文共 1270 字,大约阅读时间需要 4 分钟。

今天阅读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似乎比较容易理解一些,似懂非懂吧,先记录下来。

转载于:https://www.cnblogs.com/cruze/p/3684157.html

你可能感兴趣的文章
cocos2d-html5 让图层阻挡下层触碰事件
查看>>
POJ 1850 Code 数位DP
查看>>
Ubuntu linux设置从当前目录下加载动态库so文件
查看>>
【Linux开发】CCS远程调试ARM,AM4378
查看>>
Scala的类和对象
查看>>
table相关的选择器 & children()与find()的区别 & 选择器eq(n)与nth-child(n)的差异
查看>>
Windows Azure Platform AppFabric
查看>>
springmvc常用注解标签详解
查看>>
Linux之ssh服务介绍
查看>>
Sql语句里的递归查询(转)
查看>>
[JAVA]《Java 核心技术》(一)
查看>>
libevent机制
查看>>
rabbit ip登录
查看>>
呼叫器
查看>>
Hadoop Archives
查看>>
.Net基础篇_学习笔记_第六天_for循环语法_正序输出和倒序输出
查看>>
Java 十进制和十六制之间的转化(负数的处理)
查看>>
反射那些事儿——Java动态装载和反射技术
查看>>
Hive中的日志
查看>>
Wingdings 2 符号编码对照表
查看>>