JAVA threads (different stacks) synchronization(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
这不是真的,所以回答
如果线程执行的代码包括一些类变量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.
类成员变量存在于每个类实例的内存中的一个位置,而不是每个线程.确实,在 内存屏障之间(想想开始 {
和end }
of 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线程(不同栈)同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:JAVA线程(不同栈)同步
基础教程推荐
- 如何对 HashSet 进行排序? 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01