java并发编程之volatile

volatile

volatile 是一个类型修饰符。volatile 的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略

volatile内存语义

volatile是Java虚拟机提供的轻量级的同步机制。Java 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量,相比于synchronized(synchronized通常称为重量级锁),volatile更轻量级,因为它不会引起线程上下文的切换和调度。但是volatile 变量的同步性较差(有时它更简单并且开销更低),而且其使用也更容易出错。

volatile作用

    1.保证被volatile修饰的共享变量对所有线程总是可见的,也就是当一个线程修改了一个被volatile修饰的共享变量的值,新值总是可以被其他线程立即得知。(可见性)

    2.禁止指令重排序优化。(顺序性)

    3.volatile 只能保证对单次读/写的原子性。i++ 这种操作不能保证原子性。


volatile的可见性

关于volatile的可见性作用,我们必须意识到被volatile修饰的变量对所有线程总是立即可见的,对volatile变量的所有写操作总是能立刻反应到其他线程中。

示例:

public class VolatileVisibilityExample {
	public volatile boolean initFlag = false;
	public void save() {
		this.initFlag = true;
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} 
		String threadname = Thread.currentThread().getName();
		System.out.println("线程:"+threadname+":修改共享变量initFlag");
	}
	
	public void load(){
		String threadname = Thread.currentThread().getName();
		while (!initFlag){
			//线程在此处空跑,等待initFlag状态改变
		} 
		System.out.println("线程:"+threadname+"当前线程嗅探到initFlag的状态的改变");
	}
	public static void main(String[] args){
		VolatileVisibilityExample example = new VolatileVisibilityExample();
		Thread threadA = new Thread(()->{example.save();},"threadA");
		Thread threadB = new Thread(()->{example.load();},"threadB");
		threadB.start();
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} 
		threadA.start();
	}
}

运行结果:

线程:threadA:修改共享变量initFlag
线程:threadB当前线程嗅探到initFlag的状态的改变
线程A改变initFlag属性之后,线程B马上感知到

volatile无法保证原子性

public class VolatileVisibility {
  public static volatile int i =0;
    public static void increase(){
      i++;
  }
}

volatile禁止重排优化

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值