【多线程】内存可见性

一、什么是内存可见性

内存可见性是在编译器优化的背景下,一个线程修改了变量而另一个线程却没有感知到修改。举个例子,一个线程一直频繁的读取变量n并将n值与某一值进行比较,在底层这个操作对应着两个指令:读取内存中的n值加载到寄存器 LOAD 然后进行比较 CMP 这两个操作前者所需时间远远比后者多,短时间内重复进行LOAD、CMP操作性能低,编译器发现多次读取n值,该n值并没有被修改于是后续的读取不从主内存中读取n(内存)而是从工作内存中读取缓存的n值进行比较,这个时候另一个线程修改了内存里的n值,之前那一个线程并不能感知到

 

    static int count = 0;

	public static void main(String[] args) {
		new Thread(){
			@Override
			public void run(){
				while(count==0){

				}
			}
		}.start();

		new Thread(()->{
			try {
				Thread.sleep(2000);
				Scanner scanner = new Scanner(System.in);
				count = scanner.nextInt();
				System.out.println("count修改完成");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		}).start();
	}

当我们运行代码后输入一个值将count修改,此时发现线程1并没有结束 

二、如何避免内存可见性

我们可以通过给可能存在内存可见性的属性加上volatile关键字,该关键字可以告诉编译器每次都需要去读取内存里的值不进行编译器优化

  volatile static int count = 0;

	public static void main(String[] args) {
		new Thread(){
			@Override
			public void run(){
				while(count==0){

				}
			}
		}.start();

		new Thread(()->{
			try {
				Thread.sleep(2000);
				Scanner scanner = new Scanner(System.in);
				count = scanner.nextInt();
				System.out.println("count修改完成");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		}).start();
	}

这样当输入值修改完count后,线程1会终止

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1886i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值