聊聊volatile关键字

package net.concurrent;

public class MutableInteger {

	private int value;

	public int get() {
		return this.value;
	}

	public void set(int value) {

		this.value = value;
	}
}

在多线程环境下,MutableInteger 不是线程安全的,set/get 在没有同步的情况下访问value,数据失效的问题可能会出现。有的线程能够看到最新的数据,有些则看不到

package net.concurrent;

public class MutableInteger {

	private int value;

	public synchronized int get() {
		return this.value;
	}

	public synchronized void set(int value) {

		this.value = value;
	}
}

通过synchronized 使MutableInteger 成为线程安全的类,紧紧对set同步是不够的,因为get 仍然是会读到失效的数据,通过上一章我们清楚synchronized 是可以保证内存的可见性的,当然我们还可以使用其他的方式如下:


Volatile变量

volatile 提供了稍微弱一点的锁机制,用来确保将变量的更新操作通知到其他的线程当中,如果变量声明成volatile,表明这个变量是共享的,仅此不会出现与其他内存操作重排序操作,volatile变量不会缓存到寄存器中。因此读到volatile 操作总是最新的值。

package net.concurrent;

public class MutableInteger {

	private volatile int value;

	public int get() {
		return this.value;
	}

	public void set(int value) {

		this.value = value;
	}
}

在访问value值不会执行加锁操作,就不会出现线程堵塞状态,同时又能保证内存可见性,因此Volatile是一种比Synchronized 关键字更轻量级的同步机制.

从内存可见性的角度来分析,写入volatile变量相当于退出了同步代码块,而读取volatile变量相当于进入了同步代码块,然而我们并不建议过度的依赖volatile内存可见性。过度的应用会比synchronized的代码更脆弱也更难以理解.

虽然volatile变量很方便,但也存在一切局限性。volatile关键字通常用作于:某个操作完成、发生中断、或者状态标示.volatile不足以确保原子操作。只能保证可见性













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值