JAVA线程(不同堆栈)同步

use*_*556 5 java stack multithreading synchronization thread-safety

我有一个关于由多个线程执行的代码同步的问题:

据我所知,每个线程都有自己的堆栈,因此,非静态变量存在于每个线程的内存中的不同位置(对于X线程,存在包含所有非静态变量的X堆栈).那么为什么需要同步任何东西呢?

我的意思是,如果线程执行的代码包含一些类变量v1,那么每个线程都有自己的v1实例(不同的内存地址),没有其他线程可以"触摸"它......不是吗?

Mik*_*uel 7

非静态变量存在于每个线程的内存中的不同位置

这不是真的,所以答案是

如果线程执行的代码包含一些类变量v1,那么每个线程都有自己的v1实例(不同的内存地址),没有其他线程可以"触摸"它...是不是这样

没有.线程可以触及由其他线程分配和修改的对象实例,并且程序员负担过重以确保这不会影响程序的正确性.

类成员变量存在于内存每类实例的单个位置,而不是每个线程.这是事实之间的记忆障碍(想想开始{和结束}synchronized),一个线程可以有一个对象的状态的缓存,但毕竟是不一样的语言,规定每个线程的存储."每个线程的内存"是它的堆栈,它不包含对象成员* - 只引用对象.

想到它的最好方法是堆上有一个位置,每个对象,但可能有多个读取和写入涉及同时发生的内存位置.

如果您听说线程在堆的不同部分分配对象,我可以看到您将如何得出您所做的结论.某些JVM具有优化功能,可以进行线程局部分配,但不会阻止其他线程访问这些对象.

线程局部分配

如果分配器是真正实现的,如清单1所示,共享heapStart字段将很快成为一个重要的并发瓶颈,因为每个分配都涉及获取保护该字段的锁.为了避免这个问题,大多数JVM使用线程局部分配块,其中每个线程从堆中分配更大的内存块,并按顺序从该线程局部块中提供小的分配请求.因此,线程必须获取共享堆锁的次数大大减少,从而提高了并发性.

* - JVM优化可能允许在堆栈分配一些对象.


Kel*_*yne 2

仅保证原始类型(例如)int在堆栈上分配。对象和数组通常都存储在堆中,除非逃逸分析确定对象的范围“仅限于过程的范围”。