学习volatile

volatile关键字的特性

  1. 保证代码执行的有序性
    1. 内存屏障
  2. 可见性
    1. MESI
    2. 缓存一致性协议
  3. 但是volatile不能保证程序的原子性

 在下面这个例子里,count++表示了取值,计算和存储三个步骤,指的是不能保证这三个步骤的原子性,虽然count值可见,但是整个计算过程volatile不能保证。

package juc.volatil;

import java.util.ArrayList;
import java.util.List;

//volatile的不能保证原子性
public class T2 {
private /*volatile*/ int count = 0;
public synchronized void m() {
	for (int i = 0; i < 10000;i++) count++;
	
}
public static void main(String[] args) {
	List<Thread> threads = new ArrayList<Thread>();
	T2 t = new T2();
	for (int i = 0; i< 10;i++)
	{
		threads.add(new Thread(()-> {t.m();}));
	}
    threads.forEach((o)->{o.start();});
    threads.forEach((o)->{try {
		o.join();
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}});
    System.out.println(t.count);
}

}

volatile的底层实现

  • 可见性-缓存一致性(TBD)
    • 防止重排序-内存屏障(JMM TBD)

一个有名的singleton的线程安全实现

package juc.volatil;

public class T1 {
   private volatile static T1 INSTANCE;
   public static T1 getInstance() {
	   if(INSTANCE == null)
	   {
		   try {
			Thread.sleep(300);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		   synchronized(T1.class) {
			   INSTANCE = new T1();	   
		   }
	   }
	   return INSTANCE;
   }
   public static void main(String[] args) {
	   for(int i = 0 ;i < 100 ;i++)
	   {   new Thread(()->{
		   
		   System.out.println(T1.getInstance().hashCode());
	   }).start();
		   
	   }
   }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值