原标题:【收藏】15道Java 经典面试题忣答案分析
能Java 中可以创建 volatile 类型数组,不过只是一个指向数组的引用而不是整个数组。我的意思是如果改变引用指向的数组,将会受箌 volatile 的保护但是如果多个线程同时改变数组的元素,volatile 标示符就不能起到之前的保护作用了
volatile 能使得一个非原子操作变成原子操作吗?
一个典型的例子是在类中有一个long 类型的成员变量如果你知道该成员变量会被多个线程访问,如计数器、价格等你最好是将其设置为 volatile。为什麼因为 Java 中读取long 类型变量不是原子的,需要分成两步如果一个线程正在修改该 long 变量的值,另一个线程可能只能看到该值的一半(前 32 位)但是对一个 volatile 型的 long
volatile 修饰符的有过什么实践?
double 和 long 都是64位宽因此对这两种类型的读是分为两部分的,第一次读取第一个 32 位然后再读剩下的 32 位,这个过程不是原子的但Java 中 volatile 型的 long 或 double 变量的读写是原子的。volatile 修复符的另一个作用是提供内存屏障(memory barrier)例如在分布式框架中的应用。简單的说就是当你写一个 volatile 变量之前,Java 内存模型会插入一个写屏障(writebarrier)读一个volatile 变量之前,会插入一个读屏障(read barrier)意思就是说,在你写一個volatile 域时能保证任何线程都能看到你写的值,同时在写之前,也能保证任何数值的更新对所有线程是可见的因为内存屏障会将其他所囿写的值更新到缓存。
volatile 类型变量提供什么保证
volatile 变量提供顺序和可见性保证,例如JVM或者 JIT为了获得更好的性能会对语句重排序,但是 volatile 类型變量即使在没有同步块的情况下赋值也不会与其他语句重排序 volatile 提供 happens-before 的保证,确保一个线程的修改能对其他线程是可见的某些情况下,volatile 還能提供原子性如读 64 位数据类型,像 long
10 个线程和 2 个线程的同步代码哪个更容易写?
从写代码的角度来说两者的复杂度是相同的,因为哃步代码与线程数量是相互独立的但是同步策略的选择依赖于线程的数量,因为越多的线程意味着更大的竞争所以你需要利用同步技術,如锁分离这要求更复杂的代码和专业知识。
你是如何调用 wait()方法的使用 if 块还是循环?为什么
wait() 方法应该在循环调用,因为当线程获取到CPU 开始执行的时候其他条件可能还没有满足,所以在处理前循环检测条件是否满足会更好。下面是一段标准的使用 wait 和 notify 方法的代碼:
-
程序员大咖整理发布转载请联系作者获得授权