javavolatile
我们用一段简单的代码来开头
Java代码 收藏代码
public int i = 0;
public void increase(){
i++;
}
//getter
以上这段代码在多线程高并发的状态下能否保证所取得的i是所期待的值,答案肯定是不能的,因为对JAVA来说数据的操作是非原子性的。还有的就是部份人认为给变量i加上volatile关键字就能保证了数据操作的原子性,这显然是错误的。要记住volatile关键字只保证其可见性,也就是说当某线程修改了i的值,修改后的值对其它线程来说是立即可见的。下面我们分析通过increase()方法的字节码来解释。
Java代码 收藏代码
public void increase();
public void increase();
flags: ACC_PUBLIC
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: dup
2: getfield #2 // Field i:I
5: iconst_1
6: iadd
7: putfield #2 // Field i:I
10: return
LineNumberTable:
line 5: 0
line 6: 10
编号2到7这几行指令就是i++;的,首先getfield获取到了i的值并把它压入栈顶,在这里如果i变量有加volatile关键字,则能保证i的正确性,因为无论之前有几个线程对i作了修改,它总是能够第一时间得知。如果是普通变量的话,比如A线程对变量i修改完新值后要把它重写回主内存中,其它线程要想得知i的新值要在A线程重写回主内存之后,对这感兴趣的可以看下主线程和工作线程相关的内容。 接下来就是引发问题的关键之处了,假如当A线程准备执行相加指令时,其它线程已经把i值修改了,而A线程的操作数栈顶的值已经变为脏数据了,在执行putfield后把不正确的数据同步回主内存里。
分享到:
相关推荐
在C++编程语言中,`mutable` 和 `volatile` 是两个非常特殊的修饰符,它们各自具有独特的用途。本文将深入探讨这两个关键字的功能和使用场景。 首先,我们来看`mutable`关键字。`mutable`的主要作用是允许在const...
### 浅谈Java的多线程机制 #### 一、引言 随着计算机技术的不断发展,编程模型变得越来越复杂和多样化。多线程编程模型作为目前计算机系统架构中的一个重要组成部分,其重要性日益凸显。特别是在X86架构的硬件成为...
redis的maxmemory参数用于控制redis可使用的最大内存容量。如果超过maxmemory的值...· volatile-lru:在设置了过期时间的键空间中,优先移除最近未使用的key。 · allkeys-random:在主键空间中,随机移除某个key。
const_cast是用于去掉类型的const或volatile属性的操作符。它常用于指针或引用,例如将常量指针转换为非常量指针,以便修改指针所指向的对象的值。在多线程设计中,const_cast也常用于去掉volatile属性。 static_...
### 浅谈ARM下U-boot给Kernel传参数 在嵌入式系统开发中,U-Boot作为常用的Bootloader之一,在启动Linux内核时扮演着重要的角色。本文将深入探讨ARM架构下U-Boot如何给Linux内核传递启动参数的过程。 #### U-Boot...
5. volatile关键字:用于确保多线程环境下的可见性和有序性,但不保证原子性。如果一个变量被volatile修饰,那么所有线程都会看到最新修改的值。 6. Lock接口和ReentrantLock类:提供了比synchronized更精细的锁...
浅谈Java中ABA问题及避免 Java中的ABA问题是指在使用Compare-And-Swap(CAS)操作时可能出现的一种问题。该问题的产生是由于CAS操作的原子性和并发环境中的线程执行顺序的不确定性。ABA问题的出现可能会导致程序的...
谈到这个问题, 主要先从这几个方面来入手: · 线程的几种状态 · synchonrize的几种使用方法比较 · synchonrize和volatile比较 · synchonrize和juc中的锁比较 · 用了锁真的没有并发问题了么? ...
"浅谈Java内存模型之happens-before" Java内存模型是Java虚拟机中的一种机制,用于定义Java程序中线程之间的内存访问方式。在多线程环境下,线程之间的通信和数据共享是非常复杂的,需要有一些规则来保证数据的一致...
浅谈Java并发 J.U.C之AQS:CLH同步队列 在 Java 并发编程中,J.U.C(Java Utility Classes)提供了一些高效的并发工具,其中AQS(AbstractQueuedSynchronizer)是一个核心组件之一。AQS内部维护着一个FIFO队列,即...
总结一下,Java并发的底层实现涉及到操作系统级别的线程调度、Java内存模型(JMM)、volatile关键字的可见性保证以及无锁并发编程技术如原子类和CAS操作。理解这些概念和机制,对于编写高效、线程安全的Java并发程序...
此外,Java提供了synchronized、volatile、final等关键字来支持并发控制。synchronized保证了同一时刻只有一个线程访问特定代码块,解决了可见性和互斥问题;volatile确保了变量的修改对其他线程是立即可见的;final...
然而,提供的压缩包文件"深入浅出谈java修饰符共6页.pdf.zip"似乎包含的是一个PDF文档,若要获取更多具体信息,需要解压并查看文档内容。在"赚钱项目"这个子文件中,可能涉及的是如何利用Java编程技能进行项目开发以...
private volatile static Single3 instance; private Single3() {} public static Single3 getInstance() { if (instance == null) { synchronized (Single3.class) { if (instance == null) { instance = ...
private volatile Boolean isTrue = false; public void aMethod() { ... synchronized(isTrue) { isTrue = !isTrue; // 访问临界资源 isTrue = !isTrue; } } ``` 在这个例子中,由于`isTrue`在`synchronized...
Java提供了多种同步机制,包括synchronized关键字、volatile关键字、Lock接口、Atomic变量等。 六、线程池 线程池是指一组可以重复使用的线程,线程池可以大大减少创建和销毁线程的开销,提高系统的性能。Java提供...
private volatile static LogUtil logUtilInstance; // ... public static LogUtil getInstance() { if (logUtilInstance == null) { synchronized (LogUtil.class) { if (logUtilInstance == null) { ...