JAVA线程(不同堆栈)同步 [英] JAVA threads (different stacks) synchronization

查看:114
本文介绍了JAVA线程(不同堆栈)同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a question regarding synchronization of code that is executed by several threads:

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

As far as I know each thread has its own stack, hence, non-static variables exist in different locations in the memory for each thread (for X threads there are X stacks that include all non-static variables). So why there's a need to synchronize anything?

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

I mean, if the code that the threads execute includes some class variable v1, then each thread has its own "instance" of v1 (different memory address), and no other thread can "touch" it... isn't it so?

推荐答案


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

non-static variables exist in different locations in the memory for each thread

这是不是这样,所以答案

This is not true, so the answer to


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

if the code that the threads execute includes some class variable v1, then each thread has its own "instance" of v1 (different memory address), and no other thread can "touch" it... isn't it so

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

is no. Threads can touch object instances allocated and modified by other threads and the burden is on the programmer to ensure this does not affect program correctness.

类成员变量存在于一个地方在每个类的内存实例中,而不是每个线程。确实在内存障碍之间(想想开始 {和结束} synchronized ),一个线程可能有一个对象状态的缓存,但这与强制每线程存储的语言不同。 每个线程的内存是它的堆栈,它不包含对象成员* - 只引用对象。

Class member variables exist in a single place in memory per-class instance, not per thread. It is true that between memory barriers (think the start { and end } of synchronized), that a thread may have a cache of the state of an object, but that is not the same as the language mandating per-thread storage. The "memory for each thread" is its stack which does not contain object members* -- only references to objects.

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

The best way to think of it is that there is one location on the heap for each object, but that there might be multiple reads&|writes involving that memory location happening at the same time.

我可以看到你将如何如果您听说线程在堆的不同部分分配对象,那么您会得出结论。一些JVM有一个优化,他们可以线程本地分配但这并不妨碍其他线程访问这些对象。

I can see how you would come to the conclusions you did if you heard that threads allocate objects in different parts of the heap. Some JVMs have an optimization whereby they do thread-local allocation but that does not prevent other threads from accessing those objects.


线程本地分配

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

If the allocator were truly implemented as shown in Listing 1, the shared heapStart field would quickly become a significant concurrency bottleneck, as every allocation would involve acquiring the lock that guards this field. To avoid this problem, most JVMs use thread-local allocation blocks, where each thread allocates a larger chunk of memory from the heap and services small allocation requests sequentially out of that thread-local block. As a result, the number of times a thread has to acquire the shared heap lock is greatly reduced, improving concurrency.

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

* - it's possible that JVM optimizations allow some objects to be allocated on the stack.

这篇关于JAVA线程(不同堆栈)同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆