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);

}

}

}

现在,为什么你不能只使用私有静态int温度?实际上你可以(从某种意义上说你的程序不会爆炸或者其他东西),但是其他线程对温度的改变可能对主线程“可见”,也可能不是“可见”.

基本上这意味着你的应用甚至可能.如果你不使用挥发性物质,那么今天的温度永远是0(实际上,这个值最终会变得可见.但是,你不应该冒险在必要时不使用挥发性物质,因为它可能导致令人讨厌的错误(由于 – 完全构造的物体等).

如果将volatile关键字放在不需要volatile的东西上,它不会影响代码的正确性(即行为不会改变).在性能方面,它将取决于JVM实现.从理论上讲,由于编译器无法进行重新排序优化,不得不使CPU缓存等无效,因此可能会出现性能下降,但编译器可能再次证明您的字段永远不会被多个线程访问并消除volatile的影响完全关键字并将其编译为相同的指令.

编辑:

回复此评论:

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

你可以,它会表现正常.使用volatile可以完成的任何事情都可以通过同步来完成,但反之亦然.如果可以的话,有两个原因你可能更喜欢易变:

>减少错误:这取决于上下文,但在许多情况下使用volatile不太容易出现并发错误,比如在持有锁时阻塞,死锁等.

>更高性能:在大多数JVM实现中,volatile可以具有更高的吞吐量和更好的延迟.然而,在大多数应用中,差异太小而无关紧要.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值