网站背景音乐怎么做种植园网站模板
2025/12/29 7:56:02 网站建设 项目流程
网站背景音乐怎么做,种植园网站模板,企业官网免费,广州最新动态文章目录为什么需要volatile#xff1f;先看看并发编程的“坑”volatile的两大“超能力”1. 可见性保证2. 禁止指令重排序volatile的实现原理#xff1a;底层探秘内存屏障#xff1a;volatile的“守护神”硬件层面的支持#xff1a;LOCK前缀指令volatile的局限性#xff1…文章目录为什么需要volatile先看看并发编程的“坑”volatile的两大“超能力”1. 可见性保证2. 禁止指令重排序volatile的实现原理底层探秘内存屏障volatile的“守护神”硬件层面的支持LOCK前缀指令volatile的局限性它不是什么都能做volatile的应用场景恰到好处的使用1. 状态标志2. 一次性安全发布3. 独立观察模式4. volatile bean模式总结正确使用volatile的要点参考文章掌握volatile关键字告别可见性与有序性困扰大家好我是你们的技术老友“科威舟”——今天我们来聊聊Java并发编程中的“小身材大能量”的volatile关键字。它在多线程编程中扮演着至关重要的角色却经常被误解或低估。让我们一起 揭开它的神秘面纱为什么需要volatile先看看并发编程的“坑”想象一下你和你的小伙伴共同编辑一份在线文档共享变量你修改了内容但你的小伙伴却看不到最新版本这会造成什么后果这就是典型的可见性问题。在并发编程中每个线程都有自己的工作内存相当于CPU缓存当一个线程修改了共享变量其他线程不一定能立即看到这个修改。这就像你更新了在线文档但你的同事仍然看到的是缓存中的旧版本。除了可见性问题还有指令重排序的陷阱。编译器和处理器为了优化性能可能会重新排序指令执行顺序这在单线程下没问题但在多线程环境下可能导致意想不到的结果。volatile的两大“超能力”volatile关键字虽然看起来简单但它具备两项重要特性堪称并发编程的“双刃剑”。1. 可见性保证当一个变量被声明为volatile后对该变量的任何写操作都会立即刷新到主内存中而对该变量的读操作都会从主内存中读取。这就好比有一个严格的图书管理员每当有人还书写操作他立即将书放回正确位置每当有人借书读操作他确保给出的是最新的版本。publicclassVolatileExample{privatestaticvolatilebooleanflagfalse;publicstaticvoidmain(String[]args){ThreadwriterThreadnewThread(()-{try{Thread.sleep(1000);// 模拟一些工作flagtrue;// 写入volatile变量System.out.println(标志位已设置为true);}catch(InterruptedExceptione){e.printStackTrace();}});ThreadreaderThreadnewThread(()-{while(!flag){// 循环直到检测到flag变为true}System.out.println(检测到标志位变化线程退出);});readerThread.start();writerThread.start();}}在这个例子中如果没有volatilereaderThread可能永远检测不到flag的变化导致无限循环。而使用volatile后可以确保可见性。2. 禁止指令重排序volatile的第二个魔法是禁止指令重排序。编译器和处理器的重排序优化在单线程环境下没有问题但在多线程环境下可能导致诡异的问题。最经典的例子就是双重检查锁定DCL单例模式publicclassSingleton{privatestaticvolatileSingletoninstance;privateSingleton(){// 私有构造函数}publicstaticSingletongetInstance(){if(instancenull){// 第一次检查synchronized(Singleton.class){if(instancenull){// 第二次检查instancenewSingleton();// 注意这里}}}returninstance;}}为什么instance需要volatile因为instance new Singleton()这行代码包含三个步骤分配对象内存空间初始化对象将引用指向分配的内存地址如果没有volatile步骤2和3可能被重排序导致其他线程获取到未完全初始化的对象使用volatile可以防止这种重排序。volatile的实现原理底层探秘现在让我们深入底层看看volatile是如何实现这些神奇特性的。内存屏障volatile的“守护神”volatile的关键实现机制是内存屏障Memory Barrier。内存屏障是一种CPU指令用于控制特定操作顺序就像一道屏障确保屏障前后的指令不会越过它执行。JVM在volatile读写操作前后插入内存屏障在volatile写操作前后前面插入StoreStore屏障禁止上面的普通写与volatile写重排序后面插入StoreLoad屏障禁止volatile写与下面可能的volatile读/写重排序在volatile读操作前后后面插入LoadLoad屏障禁止下面的普通读与volatile读重排序后面插入LoadStore屏障禁止下面的普通写与volatile读重排序硬件层面的支持LOCK前缀指令在x86架构下volatile的写操作会生成带有LOCK前缀的指令。这个LOCK前缀可不是锁总线那么简单现代CPU使用缓存一致性协议如MESI协议来实现。当CPU发现要操作的变量被volatile修饰时会将当前处理器缓存行的数据立即写回主内存这个写回操作会使其他CPU中缓存该内存地址的数据无效这就像在一个团队会议上当某人更新了共享文档后立即通知所有人“文档已更新请重新加载”volatile的局限性它不是什么都能做虽然volatile很强大但它并不是万能的。最关键的局限性是volatile不能保证原子性。什么是原子性一个操作要么完全执行要么完全不执行中间不会被打断。但volatile不能保证复合操作的原子性。最经典的例子就是i操作publicclassAtomicityExample{privatestaticvolatileintcount0;publicstaticvoidmain(String[]args)throwsInterruptedException{Threadt1newThread(()-{for(inti0;i10000;i){count;// 这不是原子操作}});Threadt2newThread(()-{for(inti0;i10000;i){count;// 这不是原子操作}});t1.start();t2.start();t1.join();t2.join();System.out.println(最终结果: count);// 可能小于20000}}为什么volatile不能保证原子性因为count实际上包含三个步骤读取count的值将值加1将新值写回count在多线程环境下两个线程可能同时读取到相同的值然后分别加1并写回导致结果不符合预期。如果需要保证原子性应该使用synchronized、Lock或Atomic类。volatile的应用场景恰到好处的使用既然了解了volatile的能力和限制我们在什么情况下应该使用它呢1. 状态标志最经典的用法是作为一个简单的状态标志publicclassTaskRunnerimplementsRunnable{privatevolatilebooleanrunningtrue;publicvoidrun(){while(running){// 执行任务}}publicvoidstop(){runningfalse;}}这种情况下使用volatile是完美的因为只有一个线程修改running标志多个线程读取它。2. 一次性安全发布volatile可以用于安全发布不可变对象publicclassResourceFactory{privatevolatileResourceresource;publicResourcegetResource(){if(resourcenull){synchronized(this){if(resourcenull){resourcenewResource();// 安全发布}}}returnresource;}}3. 独立观察模式定期发布观察结果供程序其他部分使用publicclassTemperatureSensor{privatevolatiledoublecurrentTemperature;privatevoidsenseTemperature(){while(true){// 读取温度传感器currentTemperaturereadSensor();Thread.sleep(1000);}}publicdoublegetTemperature(){returncurrentTemperature;// 总是读取最新值}}4. volatile bean模式在特定情况下可以将bean的所有成员变量都声明为volatile但这适用于特定场景。总结正确使用volatile的要点volatile保证可见性一个线程修改volatile变量其他线程立即可见volatile保证有序性通过内存屏障禁止指令重排序volatile不保证原子性复合操作如i仍需其他同步机制volatile比synchronized更轻量不会引起线程上下文切换volatile关键字是Java并发编程中的重要工具虽然它不能解决所有并发问题但在适当的场景下它是一个简单高效的解决方案。理解其底层原理和适用场景有助于我们编写更安全、高效的多线程程序。希望本文能帮助你更好地理解和应用volatile关键字如果你有更好的例子或经验欢迎在评论区分享。参考文章https://bbs.huaweicloud.com/blogs/386846https://www.cnblogs.com/hanease/p/15864913.htmlhttps://blog.csdn.net/bbj12345678/article/details/120584166https://juejin.cn/post/7018357942403465246https://juejin.cn/post/7132479957938225159更多技术干货欢迎关注微信公众号科威舟的AI笔记~【转载须知】转载请注明原文出处及作者信息

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询