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

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

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?事实上,你可以(在某种意义上,你的程序不会爆炸或某物),但是其他线程的温度变化可能或可能不是“可见”的主线程。

基本上这意味着,甚至可能是你的应用程序。保持写入如果你不使用volatile,今天的温度永远是0(在实践中,值往往会变得最终可见。但是,你不应该冒险在必要时不使用volatile,因为它可能导致讨厌的错误完全构造的对象等)。

如果你把volatile关键字放在不需要volatile的东西上,它不会影响你的代码的正确性(即行为不会改变)。在性能方面,它将取决于JVM实现。在理论上你可能会得到一个微小的性能退化,因为编译器不能做重排序优化,必须使CPU缓存等无效,但然后再次编译器可以证明你的字段不能被多个线程访问,并消除volatile关键字,并将其编译为相同的指令。

编辑:

回复此评论:

Ok, but why can’t we make todaysTemperature synchronized and create a synchronized getter for temperature?

你可以和它的行为正确。任何你可以与volatile可以做同步,但不是相反。如果您可以:

>更少的bug容易:这取决于上下文,但在许多情况下使用volatile不容易发生并发错误,例如阻塞锁定,死锁等。>更高性能:在大多数JVM实现中,volatile可以具有显着更高的吞吐量和更好的延迟。然而,在大多数应用中,差异太小而不重要。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值