`

volatile

阅读更多
正确使用volatile

在jdk5修正了volatile的语义后,volatile作为一种轻量级的同步策略就得到了大量的使用。volatile的严格定义参考jvm spec,这里只从volatile能做什么,和不能用来做什么出发做个探讨。

volatile可以用来做什么?

1)状态标志,模拟控制机制。常见用途如控制线程是否停止:

private volatile boolean stopped; 
public void close(){ 
   stopped=true; 


public void run(){ 

   while(!stopped){ 
      //do something 
   } 
    
}
前提是do something中不会有阻塞调用之类。volatile保证stopped变量的可见性,run方法中读取stopped变量总是main memory中的最新值。

2)安全发布,如修复DLC问题。

private volatile IoBufferAllocator instance; 
public IoBufferAllocator getInsntace(){ 
    if(instance==null){ 
        synchronized (IoBufferAllocator.class) { 
            if(instance==null) 
                instance=new IoBufferAllocator(); 
        } 
    } 
    return instance; 
}
3)开销较低的读写锁

public class CheesyCounter { 
    private volatile int value; 

    public int getValue() { return value; } 

    public synchronized int increment() { 
        return value++; 
    } 

synchronized保证更新的原子性,volatile保证线程间的可见性。

volatile不能用于做什么?

1)不能用于做计数器

public class CheesyCounter { 
    private volatile int value; 

    public int getValue() { return value; } 

    public int increment() { 
        return value++; 
    } 
}
因为value++其实是有三个操作组成的:读取、修改、写入,volatile不能保证这个序列是原子的。对value的修改操作依赖于value的最新值。解决这个问题的方法可以将increment方法同步,或者使用AtomicInteger原子类。

2)与其他变量构成不变式

一个典型的例子是定义一个数据范围,需要保证约束lower< upper。

public class NumberRange { 
    private volatile int lower, upper; 

    public int getLower() { return lower; } 
    public int getUpper() { return upper; } 

    public void setLower(int value) {  
        if (value > upper)  
            throw new IllegalArgumentException(); 
        lower = value; 
    } 

    public void setUpper(int value) {  
        if (value < lower)  
            throw new IllegalArgumentException(); 
        upper = value; 
    } 

尽管讲lower和upper声明为volatile,但是setLower和setUpper并不是线程安全方法。假设初始状态为(0,5),同时调用setLower(4)和setUpper(3),两个线程交叉进行,最后结果可能是(4,3),违反了约束条件。修改这个问题的办法就是将setLower和setUpper同步:

public class NumberRange { 
    private volatile int lower, upper; 

    public int getLower() { return lower; } 
    public int getUpper() { return upper; } 

    public synchronized void setLower(int value) {  
        if (value > upper)  
            throw new IllegalArgumentException(); 
        lower = value; 
    } 

    public synchronized void setUpper(int value) {  
        if (value < lower)  
            throw new IllegalArgumentException(); 
        upper = value; 
    } 
}
分享到:
评论

相关推荐

    Volatile详解,深入学习Volatile

    详细说明 并举例说明了VOlatile的作用及用法,特别是嵌入式程序员要注意的

    从汇编角度理解volatile

    一般对于volatile的解释是这样的:将变量定义为volatile可以防止编译器对变量进行优化,每次均从内存中访问变量,而不是寄存器。既然让编译器优化可以提高访问速度,那为什么又要不用它以及什么时候不用它?其实主要...

    extern_volatile等修饰符的用法

    "extern_volatile等修饰符的用法" 在C++语言中,extern、volatile、const、static等修饰符都是非常重要的,它们可以影响变量的存储方式、生命周期和访问权限等。本文将详细介绍这些修饰符的用法和特点。 一、const...

    (*(volatile unsigned long *)详解

    解读volatile关键字在嵌入式系统开发中的应用 在嵌入式系统开发中,volatile关键字是一个非常重要的概念,它Playing a crucial role in ensuring that the compiler and processor do not optimize away memory ...

    C语言中关键字volatile的作用

    C语言中关键字volatile的作用,使用说明和例子

    const,extern,static,volatile的使用

    const,extern,static,volatile的使用

    volatile的使用

    一般说来,volatile用在如下的几个地方: 1、中断服务程序中修改的供其它程序检测的变量需要加volatile; 2、多任务环境下各任务间共享的标志应该加volatile; 3、存储器映射的硬件寄存器通常也要加volatile说明,...

    const和volatile分析

    const和volatile分析 这个分析得很好 面试 找工作 必备的

    volatile的用法讲解

    volatile的用法讲解,讲得很详细,希望能帮助到大家

    Java线程:volatile关键字

    主要讲述java线程volatile关键字

    volatile的使用方法

    C程序中volatile关键字的使用.方法及其例程介绍。

    C++ volatile 详解

    C++ volatile 详解 C++ 中的 volatile 关键字是用于修饰变量的,通常用于建立语言级别的 memory barrier。它是一种类型修饰符,用来声明可以被某些编译器未知的因素更改的类型变量,例如操作系统、硬件或者其它线程...

    volatile与synchronized的区别

    volatile与synchronized的区别,锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility)

    单片机C语言中volatile的作用

    本文给大家介绍了单片机C语言中volatile的作用。

    volatile_unsigned_int

    讲述了volatile_unsigned_int地址映射的使用说明。

    (*(volatile_unsigned_int_ *))

    宏定义volatile的用法,希望和大家共同学习进步。

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

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

    stm32 volatile变量的正确使用

    volatile变量的使用是区分c程序员和嵌入式系统程序员的最基本问题。不懂得volatile变量的内容将带来灾难。这个文档帮助你减少因此带来的bug。

    static,const,volatile用法

    static,const,volatile用法的解析,对三项中全局变量和局部变量的区分,volatile中介绍了其具体用法 和一些区别,bong有例子

    AVR-GCC 中如何使用volatile 关键字.pdf

    volatile 的字面含义是易变的,那么将一个变量指示为volatile 是什么意思呢?是告诉编 译器这个变量是易变的?事实上也是如此。在多任务、中断等环境下,变量可能被其他的任 务改变,而编译器无法发现,volatile ...

Global site tag (gtag.js) - Google Analytics