java中多个线程使用同一个对象会复制它吗?

8 java multithreading thread-safety thread-synchronization java-threads

Java中的多个线程如何处理传递给它们的单个对象引用

他们是复制该对象然后使用它,还是使用同一个对象?

欢迎任何技术解释。

我无法在上下文中理解这一点:如果线程将一些数据传递给对象并进入睡眠状态,而一个线程正在睡眠时,另一个线程使用同一对象将数据传递给它并进入睡眠状态。

最后一个数据会覆盖对象中的前一个数据吗?

Kam*_*zyk 6

你可以看看java内存模型。您会看到所有对象都存储在堆内存中,该内存在整个应用程序之间共享。每个线程共享相同的堆空间,但它们也有自己的堆栈内存,用于存储对对象的引用。因此,如果一个线程在对象上工作,它就有自己对该对象的引用,但该引用指向堆空间中的对象,每个线程都会看到该对象。因此,为了回答您的问题,如果第二个线程将对对象执行某些操作,然后进入睡眠状态甚至死亡,则前一个线程在唤醒时会看到这些更改,因为它的引用指向同一个对象。

我发现了一张有趣的图片,可以帮助你理解:

http://tutorials.jenkov.com/java-concurrency/java-memory-model.html

图片来自:http ://tutorials.jenkov.com/java-concurrency/java-memory-model.html


Sol*_*low 5

他们是复制该对象然后使用它,还是使用同一个对象?

实际上两者都是。

现代计算机是根据对称多处理器架构 (SMP)设计的,其中多个 CPU 竞争访问公共内存系统。为了减少竞争量,每个处理器都有自己的高速缓存(少量高速内存),其中保存属于主内存的数据的工作副本。

缓存发生在硬件中,而硬件对 Java 对象一无所知,因此它发生在逐字节级别,而不是逐对象级别。

在语言级别,对象只有一个副本,但在硬件级别,运行在不同处理器上的不同线程可以拥有自己的对象部分副本


处理器上运行的不同线程如何就某个对象的实际外观达成一致的主题称为缓存协调。

Java 对于不同线程何时以及如何协调其缓存有严格的规则。要了解有关这些规则的更多信息,请搜索“Java”和“内存模型”,或“内存可见性”,或“发生在之前”。


如果您不想阅读所有血淋淋的细节,秘诀就在于明智地使用synchronized块和synchronized方法。如果您只想记住一条规则,请记住这一点:一个线程在离开块之前对共享对象执行的任何操作都保证在这些线程进入同一锁上的synchronized块后对其他线程可见。synchronized