`
032615
  • 浏览: 60990 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

原子操作与volatile

    博客分类:
  • java
阅读更多

原子操作
    所谓原子操作,就是"不可中断的一个或一系列操作" , 因此被认为是线程安全的。实际上有一些原子操作不一定是线程安全的。

 

    在JVM 1.2之前,Java的内存模型实现总是从主存读取变量,是不需要进行特别的注意的。而随着JVM的成熟和优化,现在在多线程环境下volatile关键字的使用变得非常重要。 
    在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。
    要解决这个问题,只需要像在本程序中的这样,把该变量声明为volatile(不稳定的)即可,这就指示JVM,这个变量是不稳定的,每次使用它都到主存中进行读取。一般说来,多任务环境下各任务间共享的标志都应该加volatile修饰。
    Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。    

    Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。 

    这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。 
    而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。 
    由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。

 

    在java中,对32位或者更少位数的赋值是原子的。在一个32位的硬件平台上,除了double和long型的其它原始类型通常都是使用32位进行表示,而double和long通常使用64位表示。另外,对象引用使用本机指针实现,通常也是32位的。对这些32位的类型的操作是原子的。

 

    为什么使用volatile修饰变量后,还是不行?
因为volatile仅仅只是解决了存储的问题,即i值只是保留在了一个内存区域中,但是i++这个操作,涉及到获取i值、修改i值、存储i值(i=i+1),这里的volatile只是解决了存储i值得问题,至于获取和修改i值,确是没有做到同步。

分享到:
评论

相关推荐

    Java中的原子操作:深入探索AtomicInteger的实现与应用

    它通过 Unsafe 类提供的硬件级别的原子操作和 volatile 关键字保证了操作的原子性和可见性。在实际开发中,我们应该根据具体的应用场景选择合适的同步机制。对于简单的原子操作,AtomicInteger 是一个很好的选择。而...

    软件工程留学生Java并发编程教学研究.zip

    4. **原子操作与volatile**:Atomic类提供了一组原子操作,可以在不使用锁的情况下保证线程安全。volatile关键字保证了变量的可见性和有序性,但不保证原子性。理解这两个特性在并发编程中的应用。 5. **线程池**:...

    Java高并发编程,构建并发编程知识体系,提升面试成功率视频教程

    7. **原子操作与volatile**:Atomic类提供了一组原子操作,确保在多线程环境下更新操作的完整性。volatile关键字保证了变量的可见性和有序性,防止指令重排序。 8. **线程池**:通过ExecutorService和...

    Java-jdk10-最新最全多线程编程实战指南-核心篇

    6. **原子操作与volatile**:分析AtomicInteger、AtomicLong等原子类的原理,以及volatile关键字的作用和使用场景。 7. **线程池**:深入理解线程池的工作原理,如何自定义线程池,以及如何合理设置线程池参数以...

    JAVA并发编程实践JavaConcurrencyinPractice-中文-高清-带书签-完整版(Doug Lea)

    4. **原子操作与volatile**:讲解了Atomic类,如AtomicInteger、AtomicLong等,它们提供了一种在没有锁的情况下实现线程安全的方式。同时,对volatile关键字的使用场景和机制进行了深入解析。 5. **线程池**:详细...

    atomic_ops原子操作1

    原子操作 atomic_ops 介绍 atomic_ops 是 Linux 内核中的一种原子操作,用于实现原子 counter、Bit 操作和 spinlock 接口。下面将对 atomic_ops 的原子操作进行详细介绍。 atomic_t 类型 atomic_t 是一种原子...

    Java线程:volatile关键字

    * volatile 变量不能提供原子特性,因此不能用于实现计数器、互斥锁或任何具有与多个变量相关的不变式。 * volatile 变量的使用需要满足两个条件:对变量的写操作不依赖于当前值,以及该变量没有包含在具有其他变量...

    java里的volatile关键字详解

    (a 非long 和double类型)这个操作是不可分割的,那么我们说这个操作时原子操作。 3. 有序性:Java语言提供了volatile 和synchronized 两个关键字来保证线程之间操作的有序性,volatile 是因为其本身包含“禁止指令重...

    stm32 volatile变量的正确使用

    - 即使使用了`volatile`,也不能保证数据的原子性。在多线程或多任务环境中,还需要结合互斥锁等机制来保证数据访问的一致性和安全性。 #### 结论 在嵌入式系统编程中,正确使用`volatile`关键字对于避免潜在的bug...

    java 并发操作之原子性与可视性1

    然而,由于`a++`本身不是原子操作,即使`a`是`volatile`的,仍然需要额外的同步措施来确保线程安全。 总结来说,原子性和可见性是Java并发编程中两个独立但又相互关联的概念。原子性关注的是操作是否不可分割,而...

    volatile用法

    `volatile`不保证操作的原子性,而`synchronized`可以。 总的来说,`volatile`关键字在嵌入式系统编程和多线程编程中扮演着关键角色,帮助开发者处理内存一致性问题,确保程序的正确运行。理解和正确使用`volatile`...

    Linux内核同步机制

    自旋锁的实现是基于原子操作的,通过原子操作来实现锁的获取和释放。 3. 信号量 信号量是一种计数锁,它可以用于保护共享资源。信号量的实现是基于原子操作的,通过原子操作来实现锁的获取和释放。 四、死锁 ...

    Java并发编程:volatile关键字解析

    - **非原子性**:需要注意的是,虽然`volatile`关键字提供了可见性和有序性保证,但它并不能保证复合操作的原子性。例如,对于`i++`这样的操作,即使`i`是`volatile`变量,该操作也不是原子性的。 #### 五、使用...

    volatile 变量的说明

    例如,如果你有一个计数器并尝试通过多个线程同时递增,volatile并不能保证递增操作的原子性,因此仍然需要使用synchronized或者其他并发控制机制来保证。 下面是一些关于volatile的常见问题及其解答: 1. **参数...

    从volatile说到i++的线程安全问题.docx

    在实际应用中,需要根据具体情况选择合适的解决方案,例如使用锁机制、原子操作或volatile关键字。 五、相关概念 * 多线程环境 * 共享变量 * 可见性 * 原子性 * 锁机制 * volatile关键字 * i++操作 六、参考文献 ...

    Java并发编程系列- volatile

    例如,以下代码中的变量自加操作就不是一个原子操作: ```java class Counter { volatile int count = 0; public void increment() { count++; } } ``` 在多线程环境下,多个线程同时调用`increment()`方法时...

    volatile,nonatomic和atomic关键字测试

    然而,`volatile`并不保证操作的原子性,所以它不能单独解决并发问题。 接着,`nonatomic`和`atomic`与Objective-C的属性有关,它们定义了属性赋值和取值操作的线程安全性。默认情况下,Objective-C的属性是`atomic...

    volatile的使用1

    3. **原子性**:volatile不能保证复合操作的原子性,例如,`x++`操作就不是原子性的。如果需要原子性操作,可以使用`synchronized`或`java.util.concurrent.atomic`包中的原子类。 4. **应用场景**:volatile适合...

Global site tag (gtag.js) - Google Analytics