Volatile能不能保证线程安全?

简介: Volatile能不能保证线程安全?

对于volatile关键字,大家都很熟悉,字面意思也比较简单,线程共享,每个线程都能读取到主内存的最新数据,但真的用好就不是那么简单的事,为什么需要volatile来线程共享?又为什么线程读取的不是最新的数据而需要volaile来实现呢?volatile能不能保证线程安全呢?


首先要理解线程安全是什么,当不同的线程在并发运行的时候,修改的数据在不同的线程显示不同的数据,发生脏读,比如a线程修改了张三的金额从100-10=90,而b线程获取的张三金额还是100,这时候就出现了脏读,多线程个线程导致了线程不安全。Jvm虚拟机内存模型规定所有变量都存在主内存中(类似于计算机的物理内存),为了高效性,每个线程都有自己的内存,所以线程对变量的操作都会在自己工作内存中运行,因此多个线程处理一个共享变量的时候,这时候就会出现线程安全问题。

其实这时候就能想到了thredLocal,作用就是保证在多线程的情况下,每个线程都可以处理自己独立的变量,存储在自己独立的map中,那么既然java线程既然本身就是在线程独立内存运行的,为何多此一举又出现了threadLocal,这就是上面说的,为了解决多个线程处理同一个共享变量时候出现的线程不安全问题。


言归正传,volatile有三个重要的特性,可见性,有序性,线程不安全性,如果大家吧前面的看完之后,基本就可以理解可见性了,可见性就是线程在处理变量的时候,不会从自己的内存中获取,而是才能够java堆里面获取其他线程也会改变的量,这个量也可以称为最后值,永远是最新的,而有序是保证他不会重新排序,java会对有延迟的代码进行重新排序,在不影响结果的情况下,效率块的代码会放到前面执行,但volatile会保证代码不会重排序。线程是否安全呢,答案是否定的,他能保证可见性和有序性,但是不能保证原子性,因为java里的运算是非原子的,比如jvm处理一个变量需要先load到线程栈中,然后在线程栈中改变值,最后在线程退出的时候,才会改变java堆的值,这些操作不会保证原子性,synchronized可以保证原子性,说明他和synchronized不同的是,线程非安全的。

那么他可以保证线程安全吗,如果保证两点,一就是运算的结果不依赖变量的最新值,或者保证只有一个线程才能改变那个值,也就是变量值不会共享,二就是变量不需要与其他状态变量共同参与不变约束。

讲到这里就解释完了,如果有什么意见或者不对的地方,欢迎提出评论,或者与本人私聊商讨。

相关文章
|
缓存 人工智能 安全
4. Java 的线程安全机制之`volatile`
4. Java 的线程安全机制之`volatile`
|
1月前
|
存储 SQL 缓存
揭秘Java并发核心:深度剖析Java内存模型(JMM)与Volatile关键字的魔法底层,让你的多线程应用无懈可击
【8月更文挑战第4天】Java内存模型(JMM)是Java并发的核心,定义了多线程环境中变量的访问规则,确保原子性、可见性和有序性。JMM区分了主内存与工作内存,以提高性能但可能引入可见性问题。Volatile关键字确保变量的可见性和有序性,其作用于读写操作中插入内存屏障,避免缓存一致性问题。例如,在DCL单例模式中使用Volatile确保实例化过程的可见性。Volatile依赖内存屏障和缓存一致性协议,但不保证原子性,需与其他同步机制配合使用以构建安全的并发程序。
60 0
|
2月前
|
缓存 安全 算法
Java面试题:如何通过JVM参数调整GC行为以优化应用性能?如何使用synchronized和volatile关键字解决并发问题?如何使用ConcurrentHashMap实现线程安全的缓存?
Java面试题:如何通过JVM参数调整GC行为以优化应用性能?如何使用synchronized和volatile关键字解决并发问题?如何使用ConcurrentHashMap实现线程安全的缓存?
30 0
|
4月前
|
存储 安全 Java
并发编程知识点(volatile、JMM、锁、CAS、阻塞队列、线程池、死锁)
并发编程知识点(volatile、JMM、锁、CAS、阻塞队列、线程池、死锁)
93 3
|
1月前
|
缓存 Java
【多线程面试题二十三】、 说说你对读写锁的了解volatile关键字有什么用?
这篇文章讨论了Java中的`volatile`关键字,解释了它如何保证变量的可见性和禁止指令重排,以及它不能保证复合操作的原子性。
|
2月前
|
设计模式 缓存 安全
Java面试题:工厂模式与内存泄漏防范?线程安全与volatile关键字的适用性?并发集合与线程池管理问题
Java面试题:工厂模式与内存泄漏防范?线程安全与volatile关键字的适用性?并发集合与线程池管理问题
48 1
|
2月前
|
微服务
多线程内存模型问题之在单例模式中,volatile关键字的作用是什么
多线程内存模型问题之在单例模式中,volatile关键字的作用是什么
|
2月前
线程可见性和关键字volatile
线程可见性和关键字volatile
|
2月前
|
算法 安全 Java
Java面试题:解释JVM中的堆内存分代收集策略,并讨论年轻代和老年代的特点,描述Java中的线程池,并解释线程池的优点,解释Java中的`volatile`关键字的作用和使用场景
Java面试题:解释JVM中的堆内存分代收集策略,并讨论年轻代和老年代的特点,描述Java中的线程池,并解释线程池的优点,解释Java中的`volatile`关键字的作用和使用场景
35 0
|
4月前
|
安全 Java 编译器
Java多线程基础-6:线程安全问题及解决措施,synchronized关键字与volatile关键字(一)
线程安全问题是多线程编程中最典型的一类问题之一。如果多线程环境下代码运行的结果是符合我们预期的,即该结果正是在单线程环境中应该出现的结果,则说这个程序是线程安全的。 通俗来说,线程不安全指的就是某一代码在多线程环境下执行会出现bug,而在单线程环境下执行就不会。线程安全问题本质上是由于线程之间的调度顺序的不确定性,正是这样的不确定性,给我们的代码带来了很多“变数”。 本文将对Java多线程编程中,线程安全问题展开详细的讲解。
81 0