java - 将原语写入堆栈或堆?

标签 java multithreading primitive

我今天正在接受工作面试。 在一个问题上,面试官问我一个线程读取另一个线程设置的整数值需要多少时间?微秒?毫秒甚至一秒?

他告诉我,如果是long值,甚至可以达到一秒,因为“long值先写入堆栈,而读取线程从堆读取,所以要读取的值应该首先是复制到堆”,对于长值,可能需要很长时间。

有人可以告诉我我是否理解正确并对此进行更多解释吗?

谢谢!

最佳答案

how much time will it take to a thread to read an integer value that another thread set? Micro seconds? Milliseconds or even a second?

取决于很多因素。如果问题是关于 volatile intlong 字段,那么现代 CPU 上的答案通常仍然是微秒。如果该字段没有来自其他线程的频繁访问,它实际上在性能方面可以非常接近正常读取。然而,如果变量竞争严重,则根据缓存失效和内存行锁定的成本,它可能会更加昂贵。当然,如果您要访问 synchronized block 内的字段,那么这取决于线程之间的锁争用以及 block 中的其他操作。

例如,在我的 4 核 Mac 上,运行 10 个线程,所有线程都递增 volatile int,它们可以在大约 190 毫秒内执行 100 万次 ++。如果我的数学正确的话,大约是每 0.19 微秒。当然无论如何都不科学,但它应该让您对规模有所了解。更改为 volatile long 并没有对数字造成太大变化,但我在 native 64 位系统和 JVM 上运行。同样,具有大量缓存内存的大型应用程序内部的性能影响可能会接近毫秒,但远不及秒。

作为比较,它可以在大约 1300 毫秒内完成 AtomicInteger 增量,并在大约 1400 毫秒内完成 100 万次 AtomicLong 增量。同样,这些数字是一个非常简单的测试程序中的近似值。

He told me that it can reach even a second in the case of a long value, because "the long value is written first to the stack but the reading threads read from the heap, so the value to be read should first be copied to the heap" and for long values it can take a lot of time.

这没有多大意义。 intlong 之间的唯一区别是,long 可以根据运行时架构进行多次访问。例如,如果您使用 32 位体系结构,则可能需要多次访问才能读取和更新 64 位值。但是,访问 long 需要花费几秒钟的想法,因为它是宽度的两倍,这是无效的。

how much time will it take to a thread to read an integer value that another thread set?

正如其他人所提到的,如果这是在谈论一个线程何时会看到另一个线程中对变量进行不同步更新,那么答案肯定是秒,但这与变量的宽度几乎没有关系,也没有任何关系。与堆栈和堆之间的复制有关。

关于java - 将原语写入堆栈或堆?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47537992/

相关文章:

java - 为什么 Bruce Eckel 说只能将对象传递给 Java 中的方法?

C#正确高效的 double 到十进制的转换

android - 捕获 BluetoothSocket InputStream.read() 超时的线程

java.lang.ClassCastException : Application1 cannot be cast to Application2

java - Storm 不尊重最大喷口支出

java - 在调用方法之前检查两个可选内容

c# - Dictionary<,> 索引器中使用离散键并发写入的线程安全

java - 从线程返回时设置非基本类型

javascript - 对象与原始对象

java - 为什么对于某些文件,getResourceAsStream()和使用FileInputStream读取文件会返回不同长度的数组?