易失性关键字和线程本地内存[关闭]

Posted

技术标签:

【中文标题】易失性关键字和线程本地内存[关闭]【英文标题】:Volatile Keyword & the thread local memory [closed] 【发布时间】:2012-12-30 07:59:35 【问题描述】:

我对 Java 中 volatile 关键字的用法感到困惑。我在互联网上阅读了很多文章,但仍然一无所获。我脑子里有很多问题想问:

首先,***和许多博客都说所有volatile 变量都存储在一个线程本地内存,在所有线程共享的主内存上!我有点困惑,它们是指stack memory 吗?我知道每个线程都有自己的stack memory,它存储自己的原始文字和对象引用。

如果是这样,那么如果 volatile 变量是对象引用而不是原始文字会发生什么?我猜所有的对象都存储在堆空间而不是堆栈内存中。

其次,您能否通过示例详细说明volatile 关键字的工作原理以及我们应该何时使用它?

【问题讨论】:

您在哪里读到 volatile 变量存储在线程本地内存中?我在***条目中没有看到这样的断言。 “***和许多博客都说所有易失性变量都存储在线程本地内存中,而不是所有线程共享的主内存!”。请提供带有链接的引用。这听起来不对。 The Java Tutorials: Atomic Access 和 Java theory and practice: Managing volatility 比***更适合阅读 volatile en.wikipedia.org/wiki/Volatile_variable#In_Java :没有说明你所说的内容。 我想我犯了一个大错误,我不得不说 volatile 变量存储在主内存中,而不是本文中所说的线程本地内存中:javamex.com/tutorials/synchronization_volatile.shtml我的应用. @Stephen C:这是一个谈论线程本地内存的例子。现在,线程本地内存和进程缓存内存有什么区别?! 【参考方案1】:

首先,***和许多博客都说所有易失性变量都存储在线程本地内存中,而不是所有线程共享的主内存。

这是不正确的。可变字段是实例或类(静态)变量,存储在堆中。

他们可能指的是特定于单个处理器/内核的高速缓存内存......但这是特定于硬件的事情。但这绝对不是“线程本地的”。这个词的意思完全不同。

如果是这样,那么如果 volatile 变量是对象引用而不是原始字面量会发生什么?

没什么特别的。你的假设是错误的。

易失性变量不存储在堆栈中。实际上,如果您尝试将 volatile 关键字用于局部变量,您将收到编译错误。 (这是没有意义的。堆栈上的变量只对一个线程可见。可变语义是关于由不同线程共享的变量。)

我知道每个线程都有自己的堆栈内存,它存储自己的原始文字和对象引用。

线程栈中存储的是:

方法的局部变量, 方法的参数, 方法的返回地址等,以便 CPU 在调用返回时知道去哪里,并且(可能) JIT 编译器认为不需要将本地对象的状态存储在堆中。

方法的原始文字通常嵌入在代码本身中。字符串文字也在其他地方。 (当这些文字被分配给局部变量时,它们将被保存在堆栈中......)

其次,您能否通过一个示例详细说明 volatile 关键字的工作原理以及我们应该何时使用它?

检查 cmets 和相关问题......或谷歌“java volatile example”。解释是多余的。

【讨论】:

你的答案+1。但是,您没有在“存储在线程堆栈上的内容是:”中提到在方法内创建的对象的参考值。这是否意味着在方法中创建的对象将存储在堆栈本身中?不在堆中? 在方法中创建的对象的引用不需要特别提及。它们可能存储在局部变量中(在堆栈中......已经覆盖),或者在类变量、实例变量或数组中(在堆中)。 我的最后一个要点是指一些 JIT 编译器在启用“转义分析”时可能执行的特定优化。在这种情况下,整个对象存储在堆栈内存中。如果 JIT 编译器可以推断出有问题的对象不能从当前方法中“逃脱”,则可以执行此优化。

以上是关于易失性关键字和线程本地内存[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

多线程中的Java volatile关键字

Java 内存模型:易失性变量和发生前

CYPRESS代理64Kbit非易失性铁电存储器FM25640B

2018-2019-1 20165325 《信息安全系统设计基础》第五周学习总结

在这个多线程 C++ 代码中是不是需要“易失性”?

高 GPU 内存使用但零易失性 gpu-util