java - Java多线程—如果我们有共享堆,为什么我们需要查看主内存(RAM)?

标签 java multithreading caching shared-memory heap-memory

如果我们使用volatile关键字,线程将从主内存中读取而不是从其自己的缓存中读取。如果我们有通用的堆内存,那为什么我们需要查看主内存?我们是否要说主内存(RAM)和堆相同?

最佳答案

这个问题有两个方面。
堆/RAM/主内存
在这种情况下,术语“RAM”和“主存储器”指的是同一件事。我将在本文的其余部分中介绍RAM。这些术语在硬件级别和软件级别有意义。
堆是在软件级别使用的术语,仅表示可以在其中创建对象的RAM区域。
在软件级别上,除了堆之外,还有堆栈。堆栈也是RAM中的存储区。在Java中,堆栈只能包含int或long之类的原始数据类型,以及位于堆内部的指向对象的指针(内存地址)。
易失
在程序员不可见的硬件级别上,有许多内存缓存可用于缓存经常重复使用的数据。这使计算机运行速度更快,因为内存访问花费的时间更少。在几乎所有情况下,作为程序员,您都不会在任何地方看到这些缓存。您只能在某些特殊情况下注意到性能的提高。
当多个CPU内核(想到线程)访问RAM中的相同内存地址时,它们访问的数据实际上可能来自RAM与CPU之间的高速缓存。如果变量而不是标记为volatile,则这些缓存可以包含不同的数据,因此不同的CPU内核将为同一内存地址接收不同的数据。这通常是不希望的。因此存在volatile关键字。如果将变量标记为volatile,则CPU内核确保它们直接从RAM读取,并且更新内存将写回RAM,以确保其他CPU内核可以访问最新值。

关于java - Java多线程—如果我们有共享堆,为什么我们需要查看主内存(RAM)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62914811/

相关文章:

java - 默认情况下,Maven 中是否可以同时激活多个配置文件?

java - 使用非 Spring Boot 应用程序进行 Spring Boot 测试

java - MySQL/Hibernate SQLQuery 如何将 unsigned int(10) 转换为smallint?

java - 'java -cp' 命令行不工作

php - PHP (CakePHP) 中的异步处理或消息队列

c# - 使用C#在mysql中插入海量流数据

c# - 为什么线程进入休眠模式C#

java - 无法使用 Spring Cacheable 在 Aerospike Cache 中添加记录

ruby-on-rails - 如何使用 cache_path 使 caches_action 过期?

php - 有没有一种方法或工具可以自动访问我网站的所有页面