Java多线程——volatile详解

本文深入探讨了Java中volatile关键字的内存语义,包括其可见性和禁止指令重排序的作用,以及与synchronized关键字的区别。通过实例展示了如何利用volatile检查状态标记以决定是否退出循环。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

volatile的内存语义

(1)可见性

(2)禁止指令重排序

注:volatile的非原子性,在i++或i=i+1;会出现不安全。

可见性——缓存一致性协议

(1)Lock前缀指令会引起处理器缓存写到内存,线程的本地内存失效,别的线程只能从主存中读取数据。而本地内存的值会立马刷新到主存中去。(Lock又分为锁总线还是锁缓存)

(2)一个处理器的缓存回写到内存会导致其他处理器的缓存无效。

禁止指令重排序——内存屏障

volatile用途

 检查某个状态标记以判断是否退出循环

public class Demo {
	
	public volatile boolean run = false;
	
	public static void main(String[] args) {
		
		Demo d = new Demo();
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				for(int i = 1;i<=10;i++) {
					System.err.println("执行了第 " + i + " 次");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				d.run = true;
			}
		}).start();
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				while(!d.run) {
					// 不执行
				}
				System.err.println("线程2执行了...");
			}
		}).start();

volatile和synchronized的区别?

(1)volatile保证变量的可见性,即只保证了对volatile变量读和写操作的原子性,并不能保证对i++这种复合操作的原子性。                  而synchronized则是锁定当前临界资源,只有当前线程可以访问该资源,其他线程被阻塞住。保证了可见性和原子性。

(2)volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和代码块和类。

(3)volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值