Hi 大家好,我是 DHL,大厂程序员,公众号:ByteCode ,在美团、快手、小米工作过。搞过逆向,做过性能优化,研究过系统,擅长鸿蒙、Android、Kotlin、性能优化、职场分享。
来自微信小程序「猿面试」每日分享一道大厂面试题,涉及 Java
、Android
、鸿蒙和ArkTS
、设计模式
、算法和数据结构
等内容。
volatile 和 synchronized 的区别
在 Java 中,volatile
和 synchronized
都是用于控制多线程环境下的并发访问,但它们的作用和使用场景有所不同。
可见性:
volatile
关键字确保变量的修改对所有线程是可见的。当一个线程修改了 volatile
变量的值,这个修改会立即被写入主内存,并且其他线程在读取该变量时会从主内存中获取最新的值。然而,volatile
只保证变量本身的可见性,不保证整个代码块的可见性。这是通过禁止指令重排序和强制将缓存中的数据写回主内存来实现的。
synchronized
关键字不仅保证变量的可见性,还保证整个代码块的可见性。当一个线程进入 synchronized
代码块时,它会从主内存中读取所有变量的最新值,并且在退出 synchronized
代码块时,所有修改过的变量都会被刷新到主内存中。
作用范围:
volatile
只能用于修饰变量,不能用于修饰方法或代码块。
synchronized
可以用于变量、方法或代码块。
原子性:
volatile
不能保证操作的原子性,也就是说,它不能保证复合操作的原子性。例如,volatile int count = 0;
,如果多个线程同时执行 count++
,仍然可能会出现竞态条件,因为 count++
实际上是读-修改-写三个步骤的组合。
synchronized
可以保证操作的原子性。当一个线程进入 synchronized
代码块时,其他线程无法同时进入该代码块,从而保证了操作的原子性。
阻塞性:
volatile
不会造成线程阻塞,因为它不涉及锁机制。
synchronized
可能会造成线程阻塞,因为它涉及到锁的获取和释放,当一个线程持有锁时,其他线程必须等待
性能:
volatile
的性能优于 synchronized
,因为它不需要加锁和释放锁,只是简单地通知 JVM 从主内存中读取或写入变量。
synchronized
的性能相对较低,因为它涉及到锁的获取和释放,可能会导致线程阻塞和上下文切换
应用场景:
volatile
适用于只需要保证变量可见性的场景,例如标志位的更新。
synchronized
适用于需要保证操作原子性和代码块可见性的场景,例如多个线程对共享资源的访问。
总结
volatile
更轻量级,主要用于确保变量的可见性和防止指令重排序,但不适用于需要原子性的复合操作。
synchronized
则更为强大和通用,既能确保可见性也能确保原子性,但可能会带来更大的性能开销。
在某些情况下,也可以将 volatile
和 synchronized
结合起来使用,以实现更精细的线程控制,比如常用单例模式。
更多大厂面试题,欢迎前往微信搜索小程序 「猿面试」 查看。微信小程序 (猿面试) 包含了 Java
、Android、鸿蒙和ArkTS
、设计模式
、算法和数据结构
相关内容,
更多面试题:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/22146,转载请注明出处。
评论0