java - 为 putLock 和 count 制作本地副本的目的是什么?
问题描述
这段代码来自jdk LinkedBlockingQueue
,我想知道为什么他们在这里制作局部变量而不是直接使用它?
final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count;
public void put(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
final int c;
final Node<E> node = new Node<E>(e)
final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count;
putLock.lockInterruptibly();
try {
/*
* Note that count is used in wait guard even though it is
* not protected by lock. This works because count can
* only decrease at this point (all other puts are shut
* out by lock), and we (or some other waiting put) are
* signalled if it ever changes from capacity. Similarly
* for all other uses of count in other wait guards.
*/
while (count.get() == capacity) {
notFull.await();
}
enqueue(node);
c = count.getAndIncrement();
if (c + 1 < capacity)
notFull.signal();
} finally {
putLock.unlock();
}
if (c == 0)
signalNotEmpty();
}
解决方案
Java 通过引用传递对象。在这种情况下,'e' 是对内存中某个对象的引用。如果您不在方法内复制它,变异操作将影响正在传递的对象,在这种情况下,这不是所需的行为。
想象一下这种情况:
Queue q = new LinkedBlockingQueue(..);
Node e = new Node(..);
q.put(e); // internal state of e is changed
//do something with e and potentially not knowing that is has changed
推荐阅读
- ios - 将应用程序上传到 iTunes 连接时如何解决 Xcode 验证错误?
- sql - 追加查询不追加缺失项
- python - 简单的神经网络误差先减小后增大
- typescript - 基于输入类型的返回类型
- python - 在 Excel 中编辑大型数据库 - 除了 VBA 之外,任何易于学习的提供数组操作的语言?Python?哪个图书馆?
- php - WordPress:无法在主页上显示标题
- android - kotlin 中的 android customViews - 在 init 块中初始化可以吗?
- python - 无法使用提供的凭据登录
- graphql - 重新绘制:远程graphql服务器的CORS错误
- android - 是否可以强制 android 应用程序进入“后台”以测试后台执行限制