java volatile什么时候用_什么时候在Java中使用volatile关键字?

2522019a9e5a3f559f8eae8f01764a82.png

慕仰8121524

当你想让一个成员变量被多个线程访问但不需要复合原子性(不确定这是否是正确的术语)时,你基本上使用它。class BadExample {

    private volatile int counter;

    public void hit(){

        /* This operation is in fact two operations:

         * 1) int tmp = this.counter;

         * 2) this.counter = tmp + 1;

         * and is thus broken (counter becomes fewer

         * than the accurate amount).

         */

        counter++;

    }}以上是一个不好的例子,因为你需要复合原子性。 class BadExampleFixed {

    private int counter;

    public synchronized void hit(){

        /*

         * Only one thread performs action (1), (2) at a time

         * "atomically", in the sense that other threads can not 

         * observe the intermediate state between (1) and (2).

         * Therefore, the counter will be accurate.

         */

        counter++;

    }}现在来看一个有效的例子: class GoodExample {

    private static volatile int temperature;

    //Called by some other thread than main

    public static void todaysTemperature(int temp){

        // This operation is a single operation, so you 

        // do not need compound atomicity

        temperature = temp;

    }

    public static void main(String[] args) throws Exception{

        while(true){

           Thread.sleep(2000);

           System.out.println("Today's temperature is "+temperature);

        }

    }}现在,为什么你不能使用private static int temperature?实际上你可以(在某种意义上说你的程序不会爆炸或者其他东西),但是temperature另一个线程的改变可能对主线程“可见”,也可能不是“可见”。基本上这意味着你的应用甚至可能。Today's temperature is 0如果你不使用volatile,它会永远写作(在实践中,这个值最终会变得可见。但是,你不应该冒险在必要时不使用volatile,因为它可能会导致令人讨厌的错误(由完全构造的对象等引起)。 )。如果将volatile关键字放在不需要的东西上volatile,它不会影响代码的正确性(即行为不会改变)。在性能方面,它将取决于JVM实现。从理论上讲,由于编译器无法进行重新排序优化,不得不使CPU缓存等无效,因此可能会出现微小的性能下降,但再次编译器可以证明多个线程无法访问您的字段并删除volatile关键字的影响完全并将其编译为相同的指令。编辑:回复此评论:好的,但是为什么我们不能让todaysTemperature同步并为温度创建一个同步的getter?你可以,它会表现正常。您可以使用的任何东西volatile都可以完成synchronized,但反之亦然。volatile如果可以,您可能会有两个理由:减少错误:这取决于上下文,但在许多情况下使用volatile不太容易出现并发错误,例如在持有锁时阻塞,死锁等。性能volatile更高:在大多数JVM实现中,可以具有更高的吞吐量和更好的延迟。然而,在大多数应用中,差异太小而无关紧要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值