volatile 有什么作用,举出三个例子
时间: 2024-09-20 18:18:03 浏览: 52
`volatile`关键字在Java中主要用于解决多线程环境下的数据可见性和内存一致性问题。它主要有以下三个关键作用:
1. 数据可见性:当一个线程修改了一个volatile变量后,其他线程立即看到这个新的值,而不是之前最后一次读取到的结果。这对于共享变量非常重要,因为通常它表示了某个状态的改变。
2. 禁止指令重排序:`volatile`可以防止CPU对缓存行的操作进行优化(如指令重排序),保证操作按程序顺序执行,避免出现不可预期的行为。
3. 防止线程间出现幻读(Heisenbug):如果一个变量是非volatile的,那么一个线程可能会看到另一个线程在更新前的旧值,这就是幻读。`volatile`保证每次访问都是从主内存加载最新的值,避免这种问题。
以下是三个关于`volatile`的示例:
1. **互斥锁**:通过一个volatile boolean类型的成员变量作为锁标志,当值为true时禁止进入临界区,可以简化并发控制。
```java
private volatile boolean isLocked = false;
public synchronized void lock() {
while (isLocked) {}
isLocked = true;
}
```
2. **线程安全的单例模式**:单例中的getInstance()方法需要返回的是唯一的实例,通常会用volatile关键字确保其可见性。
```java
private static volatile Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
```
3. **无界缓冲队列**:用volatile数组元素作为生产者和消费者之间的同步信号,防止读取到已删除的元素。
```java
public class VolatileArrayQueue<T> {
private T[] buffer;
private int head, tail;
// 使用volatile保证读取head/tail的最新值
public boolean offer(T item) {
// 添加新元素...
buffer[tail] = item;
tail = (tail + 1) % buffer.length; // 更新尾指针并保持volatile
return true;
}
// ...其他操作
}
```
阅读全文