`

正确使用 volatile 的模式

    博客分类:
  • java
 
阅读更多

很多并发性专家事实上往往引导用户远离 volatile 变量,因为使用它们要比使用锁更加容易出错。然而,如果谨慎地遵循一些良好定义的模式,就能够在很多场合内安全地使用 volatile 变量。要始终牢记使用 volatile 的限制 —— 只有在状态真正独立于程序内其他内容时才能使用 volatile —— 这条规则能够避免将这些模式扩展到不安全的用例。 

模式 #1:状态标志

也许实现 volatile 变量的规范使用仅仅是使用一个布尔状态标志,用于指示发生了一个重要的一次性事件,例如完成初始化或请求停机。 

很多应用程序包含了一种控制结构,形式为 “在还没有准备好停止程序时再执行一些工作”,如清单 2 所示: 

清单 2. 将 volatile 变量作为状态标志使用

volatile boolean shutdownRequested;

...

public void shutdown() { shutdownRequested = true; }

public void doWork() { 
while (!shutdownRequested) { 
// do stuff
}
}

很可能会从循环外部调用 shutdown() 方法 —— 即在另一个线程中 —— 因此,需要执行某种同步来确保正确实现 shutdownRequested 变量的可见性。(可能会从 JMX 侦听程序、GUI 事件线程中的操作侦听程序、通过 RMI 、通过一个 Web 服务等调用)。然而,使用 synchronized 块编写循环要比使用清单 2 所示的 volatile 状态标志编写麻烦很多。由于 volatile 简化了编码,并且状态标志并不依赖于程序内任何其他状态,因此此处非常适合使用 volatile。 

这种类型的状态标记的一个公共特性是:通常只有一种状态转换;shutdownRequested 标志从 false 转换为 true,然后程序停止。这种模式可以扩展到来回转换的状态标志,但是只有在转换周期不被察觉的情况下才能扩展(从 false 到 true,再转换到 false)。此外,还需要某些原子状态转换机制,例如原子变量。

分享到:
评论

相关推荐

    volatile使用详解

    在 `release` 模式下,如果没有使用 `volatile`,第二次读取 `i` 的值时可能不会从内存中重新读取,而是使用之前缓存的值。但使用了 `volatile` 后,每次访问 `i` 都会从内存中重新读取,确保获取的是最新值。 ####...

    volatile的使用1

    【volatile关键字】在Java编程语言中扮演着至关重要的角色,主要负责解决并发环境下的数据同步问题。volatile确保了变量在多线程环境下的...理解并正确使用volatile,可以帮助开发者编写出更高效、更安全的多线程代码。

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

    使用`volatile`关键字可以确保在多个线程试图初始化同一个对象时,能够正确地处理可见性和有序性问题。 总结来说,`volatile`关键字是Java并发编程中一个非常重要的概念。它不仅解决了多线程环境下的可见性问题,还...

    Java并发编程(18)第五篇中volatile意外问题的

    在某些复杂的并发场景下,如双重检查锁定(Double-Check Locking)模式,单纯依赖volatile可能导致“幻象实例”问题,这时需要结合synchronized来保证正确初始化单例。 文档可能还分析了volatile变量在循环中的使用...

    6vc中volatile关键字的应用共4页.pdf.zip

    在某些情况下,如双重检查锁定模式(double-checked locking pattern),即使使用了`volatile`,也可能会因为指令重排序而导致错误。因此,为了确保内存模型的正确性,还需要配合`std::atomic`或C++11的内存顺序模型...

    volatile的作用

    `volatile` 是 C 语言中的一个关键字,用于修饰变量,以指示编译器不要对包含该变量的表达式进行优化,因为该变量的值可能会由编译器不可见...在编写涉及并发或硬件交互的代码时,正确使用 `volatile` 关键字至关重要。

    violate java-Java 之 volatile 超级详解

    Java中的`volatile`关键字是多线程编程中一个非常重要的概念,它用于修饰变量,确保在并发环境下,多个线程可以正确地共享和同步数据。...理解和正确使用`volatile`,可以帮助我们编写出更加高效和可靠的多线程程序。

    设计模式之单例模式(结合工厂模式)

    DCL模式通过在实例化单例时使用 volatile 关键字和双层检查,解决了这个问题。volatile关键字保证了多线程环境下变量的可见性,避免了指令重排序,从而保证了单例的正确创建。 此外,单例模式还有几种变体,比如...

    Java Volatile 变量详解及使用方法

    3. **双检查锁定(Double-Check Locking)**:在某些情况下,可以使用`volatile`配合单例模式实现双检查锁定,避免了不必要的同步开销。但这需要对Java内存模型有深入理解,否则容易出错。 **注意事项**: 使用`...

    解开Volatile的面纱V1.1

    在Java编程语言中,`volatile`关键字是一个非常关键的元素,尤其在处理多线程并发问题时。本文将深入探讨`volatile`关键字的作用、...正确理解和使用`volatile`关键字,可以帮助开发者编写出更加高效且可靠的并发程序。

    java volatile关键字作用及使用场景详解

    - 标记状态标志:`volatile`常用于标记单例模式的双重检查锁定,或者在并发组件(如信号量、屏障)中表示状态。 - 简单计数器:当多个线程同时增加一个计数器,如果计数器是`volatile`的,尽管增加操作不是原子的,...

    深入探讨Java多线程中的volatile变量共6页.pd

    在实际应用中,volatile常用于简单的状态标记,如标志位(例如:一个线程是否应该继续运行),或者是单例模式中的Double-Check Locking(双重检查锁定)中用来确保实例化过程的正确性。不过,需要注意的是,过度依赖...

    设计模式.pdf_电子版_pdf版

    在上面的实现中,我们使用 volatile 关键字修饰 uniqueInstance,以确保多个线程能够正确地访问 uniqueInstance。使用 volatile 关键字可以避免指令重排序的问题,使得 uniqueInstance 的初始化操作能够正确地执行。...

    Java双重检查加锁单例模式的详解

    在这篇文章中,我们将探讨Java双重检查加锁单例模式的详解,包括它的优点和缺点,以及如何正确地使用它。 Java双重检查加锁单例模式的优点是延迟初始化和避免竞态条件。延迟初始化可以让程序启动更快,而避免竞态...

    一文读懂ava中的Volatile关键字使用

    2. **单例模式的双重检查锁定**:在实现双检锁时,`volatile`用来确保`Singleton`实例被正确初始化后才可见。 **示例分析**: 在给出的例子中,`VolatileWithoutUsage`类的`count`变量没有使用`volatile`修饰,导致...

    多方面解读Java中的volatile关键字.rar

    在Java编程语言中,`volatile`关键字是一个非常关键的同步原语,用于处理并发编程中的可见性和有序性问题。...然而,使用时应谨慎,因为它并不提供全面的线程保护,必须结合具体场景和需求来正确应用。

    关于volatile关键字的说明以及测试

    理解并正确使用volatile是编写可靠多线程程序和嵌入式系统代码的关键。然而,需要注意的是,过度依赖volatile可能导致难以理解和维护的代码,因此在能使用其他同步机制的地方,应优先考虑使用它们。

    volatile学习手册

    在实际编程中,volatile常用于单例模式的双重检查锁定(DCL)、发布静态初始化字段、线程中断标志等场景,以保证线程间的数据同步和正确性。 总结,volatile是Java并发编程中不可或缺的一部分,它提供了一种相对轻...

    设计模式之单利设计模式

    在这个例子中,使用了`volatile`关键字来确保在多线程环境下的正确性。`volatile`关键字的作用是禁止指令重排,防止在实例化过程中出现的部分初始化对象被其他线程访问。 #### 四、案例分析 文章中的代码片段展示...

    Java 多线程与并发(5-26)-关键字- volatile详解.pdf

    而`volatile`关键字的使用,可以禁止这种重排序,保证了初始化的正确顺序,从而避免线程安全问题。 **二、实现可见性** 可见性是指当一个线程修改了共享变量的值,其他线程能够立即看到这个修改。在没有同步机制的...

Global site tag (gtag.js) - Google Analytics