`
Lucky_BW
  • 浏览: 807 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

浅谈Volatile

    博客分类:
  • Java
阅读更多
我们用一段简单的代码来开头
public int i = 0;
public void increase(){ 
    i++;
}
//getter

    以上这段代码在多线程高并发的状态下能否保证所取得的i是所期待的值,答案肯定是不能的,因为对JAVA来说数据的操作是非原子性的。还有的就是部份人认为给变量i加上volatile关键字就能保证了数据操作的原子性,这显然是错误的。要记住volatile关键字只保证其可见性,也就是说当某线程修改了i的值,修改后的值对其它线程来说是立即可见的。下面我们分析通过increase()方法的字节码来解释。
 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后把不正确的数据同步回主内存里。
分享到:
评论
1 楼 Gradawen 2012-09-21  
嘻嘻,那有什么办法可以解决这种问题,如果volatile不能做到的话...其实= =volatile我都没用过~

相关推荐

    浅谈C++中的mutable和volatile关键字

    在C++编程语言中,`mutable` 和 `volatile` 是两个非常特殊的修饰符,它们各自具有独特的用途。本文将深入探讨这两个关键字的功能和使用场景。 首先,我们来看`mutable`关键字。`mutable`的主要作用是允许在const...

    浅谈Java的多线程机制.pdf

    ### 浅谈Java的多线程机制 #### 一、引言 随着计算机技术的不断发展,编程模型变得越来越复杂和多样化。多线程编程模型作为目前计算机系统架构中的一个重要组成部分,其重要性日益凸显。特别是在X86架构的硬件成为...

    浅谈redis的maxmemory设置以及淘汰策略

    redis的maxmemory参数用于控制redis可使用的最大内存容量。如果超过maxmemory的值...· volatile-lru:在设置了过期时间的键空间中,优先移除最近未使用的key。 · allkeys-random:在主键空间中,随机移除某个key。

    浅谈C++中强制类型转换函数

    const_cast是用于去掉类型的const或volatile属性的操作符。它常用于指针或引用,例如将常量指针转换为非常量指针,以便修改指针所指向的对象的值。在多线程设计中,const_cast也常用于去掉volatile属性。 static_...

    浅谈ARM下U-boot给Kernel传参数

    ### 浅谈ARM下U-boot给Kernel传参数 在嵌入式系统开发中,U-Boot作为常用的Bootloader之一,在启动Linux内核时扮演着重要的角色。本文将深入探讨ARM架构下U-Boot如何给Linux内核传递启动参数的过程。 #### U-Boot...

    浅谈JAVA中多线程的实现.zip

    5. volatile关键字:用于确保多线程环境下的可见性和有序性,但不保证原子性。如果一个变量被volatile修饰,那么所有线程都会看到最新修改的值。 6. Lock接口和ReentrantLock类:提供了比synchronized更精细的锁...

    浅谈Java中ABA问题及避免

    浅谈Java中ABA问题及避免 Java中的ABA问题是指在使用Compare-And-Swap(CAS)操作时可能出现的一种问题。该问题的产生是由于CAS操作的原子性和并发环境中的线程执行顺序的不确定性。ABA问题的出现可能会导致程序的...

    浅谈Java中的锁

     谈到这个问题, 主要先从这几个方面来入手:  · 线程的几种状态  · synchonrize的几种使用方法比较  · synchonrize和volatile比较  · synchonrize和juc中的锁比较  · 用了锁真的没有并发问题了么? ...

    浅谈Java内存模型之happens-before

    "浅谈Java内存模型之happens-before" Java内存模型是Java虚拟机中的一种机制,用于定义Java程序中线程之间的内存访问方式。在多线程环境下,线程之间的通信和数据共享是非常复杂的,需要有一些规则来保证数据的一致...

    浅谈Java并发 J.U.C之AQS:CLH同步队列

    浅谈Java并发 J.U.C之AQS:CLH同步队列 在 Java 并发编程中,J.U.C(Java Utility Classes)提供了一些高效的并发工具,其中AQS(AbstractQueuedSynchronizer)是一个核心组件之一。AQS内部维护着一个FIFO队列,即...

    浅谈Java 并发的底层实现

    总结一下,Java并发的底层实现涉及到操作系统级别的线程调度、Java内存模型(JMM)、volatile关键字的可见性保证以及无锁并发编程技术如原子类和CAS操作。理解这些概念和机制,对于编写高效、线程安全的Java并发程序...

    浅谈Java并发中的内存模型

    此外,Java提供了synchronized、volatile、final等关键字来支持并发控制。synchronized保证了同一时刻只有一个线程访问特定代码块,解决了可见性和互斥问题;volatile确保了变量的修改对其他线程是立即可见的;final...

    深入浅出谈java修饰符共6页.pdf.zip

    然而,提供的压缩包文件"深入浅出谈java修饰符共6页.pdf.zip"似乎包含的是一个PDF文档,若要获取更多具体信息,需要解压并查看文档内容。在"赚钱项目"这个子文件中,可能涉及的是如何利用Java编程技能进行项目开发以...

    浅谈JAVASE单例设计模式

    private volatile static Single3 instance; private Single3() {} public static Single3 getInstance() { if (instance == null) { synchronized (Single3.class) { if (instance == null) { instance = ...

    浅谈Java多线程编程中Boolean常量的同步问题

    private volatile Boolean isTrue = false; public void aMethod() { ... synchronized(isTrue) { isTrue = !isTrue; // 访问临界资源 isTrue = !isTrue; } } ``` 在这个例子中,由于`isTrue`在`synchronized...

    浅谈Java并发编程基础知识

    Java提供了多种同步机制,包括synchronized关键字、volatile关键字、Lock接口、Atomic变量等。 六、线程池 线程池是指一组可以重复使用的线程,线程池可以大大减少创建和销毁线程的开销,提高系统的性能。Java提供...

    浅谈Java编程中的单例设计模式

    private volatile static LogUtil logUtilInstance; // ... public static LogUtil getInstance() { if (logUtilInstance == null) { synchronized (LogUtil.class) { if (logUtilInstance == null) { ...

Global site tag (gtag.js) - Google Analytics