Java多线程volatile关键技术解析

版权申诉
0 下载量 61 浏览量 更新于2024-08-04 收藏 47KB DOCX 举报
Java面试题总结 多线程、并发及线程的基础问题是Java面试中常见的主题,本节将对volatile类型的变量进行详细的介绍。 **1. Java中能创建volatile数组吗?** 是的,Java中可以创建volatile类型数组,不过只是一个指向数组的引用,而不是整个数组。我的意思是,如果改变引用指向的数组,将会受到volatile的保护,但是如果多个线程同时改变数组的元素,volatile标示符就不能起到之前的保护作用了。这是因为volatile类型的数组只是保证了数组的引用是volatile的,而不是数组元素本身。因此,在多线程环境下,如果需要保证数组元素的安全性,需要使用其他同步机制。 **2. volatile能使得一个非原子操作变成原子操作吗?** volatile类型的变量可以使得非原子操作变成原子操作。一个典型的例子是在类中有一个long类型的成员变量。如果你知道该成员变量会被多个线程访问,如计数器、价格等,你最好是将其设置为volatile。为什么?因为Java中读取long类型变量不是原子的,需要分成两步,如果一个线程正在修改该long变量的值,另一个线程可能只能看到该值的一半(前32位)。但是对一个volatile型的long或double变量的读写是原子的。 **3. volatile修饰符的有过什么实践?** 一种实践是用volatile修饰long和double变量,使其能按原子类型来读写。double和long都是64位宽,因此对这两种类型的读是分为两部分的,第一次读取第一个32位,然后再读剩下的32位,这个过程不是原子的,但Java中volatile型的long或double变量的读写是原子的。volatile修复符的另一个作用是提供内存屏障(memory barrier),例如在分布式框架中的应用。简单的说,就是当你写一个volatile变量之前,Java内存模型会插入一个写屏障(write barrier),读一个volatile变量之前,会插入一个读屏障(read barrier)。意思就是说,在你写一个volatile域时,能保证任何线程都能看到你写的值,同时,在写之前,也能保证任何数值的更新对所有线程是可见的,因为内存屏障会将其他所有写的值更新到缓存。 **4. volatile类型变量提供什么保证?** volatile变量提供顺序和可见性保证,例如,JVM或者JIT为了获得更好的性能会对语句重排序,但是volatile类型变量即使在没有同步块的情况下赋值也不会与其他语句重排序。volatile提供happens-before的保证,确保一个线程的修改能对其他线程是可见的。某些情况下,volatile还能提供原子性,如读64位数据类型,像long和double都不是原子的,但volatile类型变量可以提供原子性。 volatile类型变量在Java多线程编程中扮演着重要的角色,它可以提供顺序和可见性保证,确保多线程环境下的安全性。但是,需要注意的是,volatile类型变量并不能取代同步块和锁机制,它只是在一定程度上提供了原子性和可见性保证。
2023-06-10 上传