我知道关于volatile有很多问题,但我只是被讨论搞糊涂了:Java:volatile如何保证这段代码中“数据”的可见性?
我读过的每个网站都说可以在缓存中存储一个变量(使这个值对于其他线程不可见),我甚至发现了这个例子https://dzone.com/articles/java-volatile-keyword-0
所以我的第一个问题是:Java是否在缓存中存储变量值(在哪个缓存中?l1 l2还是l3)
我的另一个问题是可见性部分。例如:
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变得不稳定,它会保证Num1、Num2和Num3的执行顺序与它定义的完全一样,但是它不能保证Num4和Num5的执行顺序?
编辑我刚读完彼得·劳瑞的文章http://vanillajava.blogspot.com.es/2012/01/demonstrating-when-volatile-is-required.html他写道,“如果没有volatile,这会以多种可能的方式分解。一种方式是,两个线程各自认为自己已经更改了值,正在等待另一个,即每个线程都有自己的值缓存副本。”
所以我更困惑了。。关于这个
很抱歉问了这个可能很愚蠢的问题,但我真的很困惑。
分配的顺序不受volatile
的影响。关键字volatile
保证多个线程访问相同的值,例如int值。这个变量的值永远不会被本地线程缓存:所有读写操作都将直接进入“主内存”。对变量的访问就好像它被封装在一个同步块中,并在自身上同步。
当您想要对这种行为进行准确描述时,了解Java语言规范总是很好的。在链接的章节中,您将找到有关线程行为和编译器重新排序的信息,以及volatile
如何在这里发挥作用的信息。
包括JVM在内的大多数程序都没有显式地将变量放置在任何特定的缓存中
唯一的选择是变量是在对象中还是在堆栈上。(你也可以选择完全避免使用变量)注意,如果你把字段放在一个对象中,jit仍然只能把它放在堆栈中,如果它可以避免创建对象的话。
使num2
volatile提供的唯一可见性保证是,如果你看到num2==20,你必须看到num1==10。您还可以保证在其他线程的某个点上看到num2==20。您可能会看到num3==3或num3==30。你可能永远不会在另一个线程中看到num3,因为它不是易变的或最终的。如果在第二次写入num2之前在另一个线程中读取该字段,可能会看到num3==0,这是未初始化的值。
每个值都有自己的缓存副本。
这不是由Java决定的,而是CPU的一个实现细节。每个核心在x64、Sparc和ARM中都有自己的L1和L2缓存。为了提高速度,这些缓存对每个内核都是本地的,这意味着它们可能彼此不同步。确保它们始终同步将大大降低它们的速度。
下面是 Java 里面的关键字。不能使用以下任一作为您的程序标识符。关键字 const 和 goto 语句被保留,即使他们目前尚未使用。true, false, 和 null 似乎是关键字,但它们实际上是字面值;你不能使用它们作为你的程序标识符。 abstract continue for new switch assert*** default goto*
关键字是不能做为变量的。Lua 的关键字不多,就以下几个: and break do else elseif end false for function if in local nil not or repeat return then true until while
模型 21.1 model 视图 21.1 view 处理器方法 21.1 handler method 处理器 21.1 handler 控制器 21.1 controller 命令对象 21.1 command object 表单返回对象 21.1 form-backing object 响应 21.1 response 视图解析器 21.1 view resolver 验证器 21.1.1
智能合约使用的语言为golang定制版,屏蔽了部分golang关键字。 package、import: 谨慎使用,所有的import的模块都只能是链上的模块,不支持引用外部模块,会校验import的模块是否在链上。代码打包成交易时,会自动删除package和import,并将import按照规则转化为数组,最终的交易里是不允许包含这两个关键字的。 go/select: 由于该操作会出现并发,导致数
关键字,C的关键字共有32个 数据类型关键字(12个) char,short,int,long,float,double,unsigned,signed,struct,union,enum,void 控制语句关键字(12个) if,else,switch,case,default,for,do,while,break,continue,goto,return 存储关键字(5个) auto,exte
问题内容: 我目前正在尝试使我的java代码(使用eclipse)执行某些功能(如果说了某件事)。我正在使用Sphinx4库,这是我目前拥有的: 我想做的是在它说的那行: 如果我的发言是Hello Computer,Hello Jarvis,Good Morning Computer或Good Morning Jarvis,则运行该功能。或者换句话说,如果语音与.gram文件中的“ public
问题内容: 我是Python的新手(通常在C#上工作),在最近的几天里开始使用它。 在一个类中,是否需要在对该类的数据成员和方法的调用之前添加前缀?因此,如果我要从该类中调用方法或从该类中获取值,则需要使用或,例如? 我只想检查一下,还没有我没有遇到过的较详细的方法。 问题答案: 没有比这更冗长的方法了。始终用于访问实例属性。请注意,与C ++不同,它不是关键字。您 可以 为方法的第一个参数指定所
C# 中的关键字是编译器预先定义好的一些单词,也可以称为保留字或者保留标识符,这些关键字对编译器有特殊的意义,不能用作标识符。但是,如果您非要使用的话也不是没有办法,只需要在关键字前面加上 前缀即可,例如 就是一个有效的标识符,而 则是一个关键字。 在 C# 中,有些关键字在代码的上下文中具有特殊的意义,例如 get 和 set,这样的关键字被称为上下文关键字(contextual keyword