Java volatile 关键字 [英] Java volatile keyword

查看:45
本文介绍了Java volatile 关键字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道有很多关于 volatile 的问题,但我只是从这个讨论中感到困惑:Java:如何 volatile 保证可见性"数据"在这段代码中?

I know that there is a lot of questions about volatile but I just got confused from this discussion: Java: how volatile guarantee visibility of "data" in this piece of code?

我读过的每个网站都说一个变量可以存储在缓存中(使这个值对另一个线程不可见)我什至发现了这个例子 https://dzone.com/articles/java-volatile-keyword-0

Every web site that I read says that a variable could be stored in cached ( making this value invisible for another threads ) I even found this example https://dzone.com/articles/java-volatile-keyword-0

所以我的第一个问题是:Java 是否将变量值存储在缓存中(在哪个?l1 l2 或 l3 中)

So my first question would be: Does Java stores variable values in cache memory ( in which one ? l1 l2 or l3 )

我的另一个问题是可见性部分.例如:

My other question is the visibility part. For example:

public int num1 = 1;
public int num2 = 2;
public int num3 = 3;
public int num4 = 4;
public int num5 = 5;
...
num1 = 10;
num2 = 20;
num3 = 30;
num4 = 40;
num5 = 50;

在这个例子中,不保证变量的执行顺序.如果我将 num2 设为 volatile,它向我保证 num1、num2 和 num3 的订单执行将与其定义的完全一样,但它不能向我保证 num4 和 num5 ?

In this example the execution order of variables is not guaranteed. If I make num2 volatile it assures me that the order execution of num1, num2 and num3 will be exactly like its defined, but its not assuring me for num4 and num5 ?

编辑我刚读完 Peter Lawrey 的文章http://vanillajava.blogspot.com.es/2012/01/demonstrating-when-volatile-is-required.html他写道:没有 volatile,这会以多种可能的方式崩溃.一种方式是,两个线程都认为它们已经更改了值并正在等待另一个线程,即 每个线程都有自己的值的缓存副本."

EDIT I just finished reading the article of Peter Lawrey http://vanillajava.blogspot.com.es/2012/01/demonstrating-when-volatile-is-required.html and he wrote "Without volatile, this breaks down in a number of possible ways. One way is that the two threads each think they have changed the value and are waiting for the other i.e. each has its own cached copy of the value. "

所以我更困惑..关于那个

Sooo I'm even more confused .. about that

抱歉问了一个可能很愚蠢的问题,但我真的很困惑.

Sorry for the probably dumb question but I really confused about that.

推荐答案

大多数程序,包括 JVM,都没有明确地将变量放在任何特定的缓存中.JIT 做出的唯一决定是

Most programs, including the JVM do not explicitly place variables in any particular cache. The only decision the JIT makes is

  • 它是否完全消除了变量?
  • 它是否将它放在一个寄存器中?是哪个?
  • 它是否将它放在内存中的堆栈上?(以及相对于堆栈顶部的位置)
  • 它是否将它放在堆上的一个对象中?(以及对象中的哪个位置)

您唯一的选择是变量是在对象中还是在堆栈中.(你也可以选择完全避免使用变量)注意,如果你把字段放在一个对象中,如果 jit 可以避免创建对象,它仍然可以只把它放在堆栈中.

The only choice you have is whether the variable is in an object or on the stack. (You also have the choice to avoid using a variable at all) note, if you place the field in an object the jit can still put it only the stack if it can avoid creating the object.

使 num2 可变提供的唯一可见性保证是,如果您看到 num2 == 20,您必须看到 num1 == 10.您还可以保证您会在某个时刻看到 num2 == 20在其他线程中.您可能会看到 num3 == 3 或 num3 == 30.您可能永远不会在另一个线程中看到 num3,因为它不是 volatile 或 final.如果您在第二次写入 num2 之前在另一个线程中读取该字段,您可能会看到 num3 == 0,这是未初始化的值.

The only visibility guarantee that making num2 volatile provides is that if you see num2 == 20 you must see num1 == 10. You are also guaranteed you will see num2 == 20 at some point in other threads. You may see num3 == 3 or num3 == 30. It's possible you might never see num3 in another thread as it's not volatile or final. You might see num3 == 0 which is the uninitialised value if you read that field in another thread before num2 is written a second time.

每个都有自己缓存的值副本.

each has its own cached copy of the value.

这不是由 Java 决定的,而是 CPU 的实现细节.每个内核在 x64、Sparc 和 ARM 中都有自己的 L1 和 L2 缓存.这些缓存对于每个核心都是本地的,以提高速度,这意味着它们可能彼此不同步.确保它们始终同步会显着降低它们的速度.

This is not determined by Java but is an implementation detail of CPUs. Each core has it's own L1 and L2 caches in x64, Sparc and ARM. These caches are local to each core for speed which means they might not be in sync with each other. Ensuring they are always in sync would slow them down dramatically.

这篇关于Java volatile 关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆