在印象中,volatile修改的变量是线程安全的,我一直这么认为,殊不知还有条件的:
1. 运算结果并不依赖变量的当前值,或者能够确保只有单一线程修改变量的值.
2. 变量不需要与其他的状态变理共同参与不变约束。
public class VolatileTest{
public static volatile int race = 0;
public static void increase(){
race++;
}
}
这个方法不是线程安全的,只需要进行多线程测试便知。
虽然race变量是线程安全,但是
race++
==>
getstatic //race
iconst_1
iadd
putstatic
return
当getstatic指令把race的值取到操作栈顶时,volatile 关键字保证了race的值在此时是正确的,但是在执行iconst_1,iadd这些指令的时候,其他线程可能已经把race的值加大了.而在操作栈顶的值变成了过期的数据,所以putstatic指令执行后就可能把较小的race值同步到内存中了.
添加锁来保证线程安全。如下:
public class VolatileTest {
private static Lock lock = new ReentrantLock();
public static volatile int race = 1;
public static void increace(){
lock.lock();
race = race + 1;
lock.unlock();
}
}
这样就是线程安全了,造成线程不安全的原因是它违返了"运算结果并不依赖变量的当前值,或者能够确保只有单一线程修改变量的值"。
多线程编程,保持原子性很重要,否则要自己来保证线程安全
此文引用自《深入JVM_多线程编程》
分享到:
相关推荐
2. **单例模式中的双重检查锁定**:在实现线程安全的单例模式时,`volatile`关键字可以用来保证实例创建过程中的可见性和有序性,避免多线程环境下可能出现的问题。 3. **懒汉式初始化**:在某些情况下,为了避免...
深入理解volatile关键字 ...volatile关键字是一个强大的工具,但需要正确地使用它,以避免线程安全问题。在使用volatile关键字时,需要遵守相关的规则,并且需要弄清楚Java内存模型,以免出现不必要的错误。
这个变量a具有可见性,但是a++依然是一个非原子操作,也就是这个操作同样存在线程安全问题。 3. 有序性:volatile关键字可以保证线程之间操作的有序性,因为其本身包含“禁止指令重排序”的语义。 三、 volatile 和...
volatile 变量可用于提供线程安全,但是只能应用于非常有限的一组用例:多个变量之间或者某个变量的当前值与修改后值之间没有约束。 正确使用 volatile 变量的条件是:对变量的写操作不依赖于当前值,以及该变量...
在Java并发编程中,volatile关键字是一种轻量级的同步机制,它用于确保变量的可见性和有序性。本文将详细探讨volatile关键字的工作原理、使用场景以及如何在实际开发中正确使用volatile。 volatile关键字是Java并发...
以前我们说过在一些简单的例子中,比如为一个字段赋值或递增该字段,我们需要对线程进行同步,虽然lock可以满足我们的需要,但是一个竞争锁一定会导致阻塞,然后忍受线程上下文切换和调度的开销,在一些高并发和性能...
本文主要讨论了volatile关键字在多线程环境下的应用,特别是解决了多线程间共享变量的可见性问题,以及i++操作的线程安全问题。 一、volatile关键字的作用 volatile关键字保证了两点: 1. 可见性:在多线程环境下...
C++中的volatile关键字是一种类型修饰符,用来修饰变量,表示该变量可以被某些编译器未知的因素更改,比如操作系统、硬件或者其它线程等。 volatile关键字的主要作用是提供对特殊地址的稳定访问,防止编译器对访问该...
例如,对于volatile变量的自增操作(i++),这个操作包括读取、增加和写回三个步骤,这三个步骤在多线程环境下不是原子的,可能会出现线程安全问题。在上述示例中,`Conter.inc()`方法中的`count++`操作,即使count...
线程安全、volatile关键字、原子性、并发包、死锁、线程池学习笔记
Java多线程volatile关键字详解 Java多线程volatile关键字...在多线程环境下,使用volatile关键字可以避免线程之间的数据不一致问题,但是需要注意volatile关键字的局限性,避免在不适合的场景下使用volatile关键字。
总结来说,volatile关键字在GD32F303单片机编程中主要用于解决与硬件交互、中断处理和多线程同步时的变量状态同步问题。正确理解和使用volatile,能帮助开发者编写出更加稳定、可靠的嵌入式系统代码。在分析和调试GD...
`这样的单次赋值操作,`volatile`可以保证其原子性,但对于`flag++`这样的复合操作,由于可能存在读、修改、写三个步骤,`volatile`无法确保这些操作的原子性,可能导致线程安全问题。 4. 使用场景: `volatile`...
volatile关键字可以用于解决多线程之间的数据不一致问题,它可以保证变量在多线程之间的可见性。volatile关键字可以用在以下几种情况: 1. 在多线程之间共享变量 2. 在读取和写入缓存的过程中 3. 在解决缓存不一致...
在Java内存模型中,为了优化性能,编译器可能会对指令进行重排序,但这可能导致线程安全问题。volatile的使用禁止了这种重排序,确保了特定语句的执行顺序,从而保证了代码的有序性。 然而,volatile并不具备...
需要注意的是,`volatile`关键字并不意味着线程安全,它只保证了可见性,而没有提供原子性、有序性等其他并发控制所需的属性。在编写多线程程序时,如果需要更高级别的同步保障,还需要使用锁、原子变量(如C++11中...
在 Java并发编程中,volatile关键字是一个非常重要的知识点,开发者需要深入了解volatile关键字的作用和使用场景,以便更好地使用volatile关键字来保证线程安全。 此外,volatile关键字的使用还需要注意以下几点: ...
在多线程环境下,线程安全问题是最重要的问题。Java内存模型(JMM)规定了多线程环境下的行为规则。了解JMM是解决多线程问题的关键。 知识点2:Java内存模型(JMM) JMM是一种规范,它规定了多线程环境下的行为...
内存栅栏和volatile关键字在多线程编程中扮演着至关重要的角色,它们是确保线程安全和正确数据同步的关键机制。本文将深入探讨这两个概念,以及它们如何在.NET环境中工作。 首先,我们要理解的是,现代计算机为了...