java - 线程之间的内存共享

标签 java multithreading java-8 forkjoinpool

我有一个场景,让我有点困惑。据我所知,每个线程都有一些本地内存。

// 100 elements in SomeArray
ArrayList SomeArray = new ArrayList();
 ForkJoinPool forkJoinPool = new ForkJoinPool(8);
        forkJoinPool.submit( () ->{
            SomeArray.parallelStream().map(e->{
              A a= new A();
              // perform some action
            });
        });
class A{

}

因此,对于上面的代码,每个线程都会创建一个 A 类的 diff 对象,并且它们只会处理该对象。我认为这不会导致任何数据不一致。我这里有两个案例,但我不确定哪一个是正确的
情况 1 - 如果两个线程共享相同的内存
然后假设一个线程创建一个具有引用“a”的 A 类对象并开始执行某些操作,然后另一个线程创建一个具有相同引用名称的新对象,但现在“a”开始指向堆中的其他内存。由于“a”存在于共享内存中,因此现在“a”将指向差异内存。因此,线程 1 正在执行的操作将开始反射(reflect)在其他对象中。
情况 2 - 如果两个线程都在本地内存中存储变量“a”
然后两个线程都会创建 diff 对象,并且由于本地内存中存在“a”引用,因此它们之间不会有重叠。
简而言之,线程 1“a”变量和线程 2“a”变量将具有相同的内存引用???

最佳答案

线程没有自己的内存来存储对象。但是当一个方法执行时,该方法执行会分配有自己的堆栈帧。堆栈帧可以存储基元和对堆分配对象的引用。

在您的代码中,变量a是在闭包执行的 block 内创建的,a是一个引用,它位于堆栈帧上,并且只有执行该变量的线程关闭就可以看到了。每次执行闭包时,它都会获得自己的堆栈帧和自己的a变量。

每个 A 类型的对象都是在跨线程共享的堆上创建的。但只有当前线程才能看到该线程执行的方法中的局部变量。

(闭包可以访问在其环境中声明的字段。这意味着如果您在声明本地 a 的闭包中嵌套另一个闭包,那么嵌套的闭包可以访问该 a,即使它会超出范围。因此,您可以创建一种具有嵌套闭包的情况,其中多个线程可以看到局部变量。但发布的代码不会这样做。)

关于java - 线程之间的内存共享,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76862157/

相关文章:

java - Thymeleaf 多文件输入在未选择任何内容时发送空文件

java - 如何在同一台机器上运行数百个 Kafka 消费者?

java - Java多线程奇怪的问题。某些线程自行关闭?

java - 如何将静态导入方法与 forEach 一起使用?

java - 使用 lambda 在 Java 流中调用带参数的构造函数

java - 根据 JobParameters 动态切换 ItemProcessor

java - @JsonbTypeDeserializer 和 @JsonbTypeSerializer 在字段中不起作用

multithreading - 如何在Matlab中对进程强制使用计时器

java - 关于ExecutorService的澄清

java - Eclipse - 安装新的 JRE (Java SE 8 1.8.0)