12
回答
volatile关键字是否会在线程里面创建副本?
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   

有的说volatile关键字会在线程里面创建副本只是更改后马上同步到主内存,有的volatile修饰的变量不会创建副本只会存在于主内存?到底哪个是对的?

举报
唯世
发帖于1年前 12回/583阅
共有12个答案 最后回答: 1年前
volatile 会创建副本  但是每次读写的时候不会操作副本 都是操作主存,应该是第一种,还有一个要说明的是 现在的cpu处理能力而言,其实只要cpu不是被跑满的情况下 工作内存的变量也会马上写入主存,类似于volatile的意思,但前提是cpu有空。

会创建副本,不过每次读写都会刷新到主内存, 所以保证了可见性。  

但运算时,又是分别在不同的线程的工作内存中进行运算,所以不能保证原子性

    0
  • AmbitorAmbitor4小时前
    volatile 会创建副本

引用来自“Ambitor”的评论

volatile 会创建副本  但是每次读写的时候不会操作副本 都是操作主存,应该是第一种,还有一个要说明的是 现在的cpu处理能力而言,其实只要cpu不是被跑满的情况下 工作内存的变量也会马上写入主存,类似于volatile的意思,但前提是cpu有空。
前面一段不好说哦。后面一段我要提异议。现在的cpu快是快,但是现在的os策略是,把数据向片外存储器(就是主板上的内存)存储的时间尽量滞后,而不是马上写入“主存”。 需要volatile的地方,通常是进程之间(线程我不谈,哈,可以参照),对一个数据存在关联的情况。该写还得写。不该写的,相反不要写。一个数据该不该写volatile,和cpu快不快没关系,和用什么策略存储到片外存储器也没关系,和内部逻辑有关系。哈。
voliate会在工作内存总存在,只是voliatle会确保读之前将写的值刷新到主内存,让读的工作内存读的值失效

引用来自“Ambitor”的评论

volatile 会创建副本  但是每次读写的时候不会操作副本 都是操作主存,应该是第一种,还有一个要说明的是 现在的cpu处理能力而言,其实只要cpu不是被跑满的情况下 工作内存的变量也会马上写入主存,类似于volatile的意思,但前提是cpu有空。

引用来自“中山野鬼”的评论

前面一段不好说哦。后面一段我要提异议。现在的cpu快是快,但是现在的os策略是,把数据向片外存储器(就是主板上的内存)存储的时间尽量滞后,而不是马上写入“主存”。 需要volatile的地方,通常是进程之间(线程我不谈,哈,可以参照),对一个数据存在关联的情况。该写还得写。不该写的,相反不要写。一个数据该不该写volatile,和cpu快不快没关系,和用什么策略存储到片外存储器也没关系,和内部逻辑有关系。哈。

java所有的变量都会拷贝副本到线程的,还有 我没有说一个数据该不该写volatile 跟cpu快是否有关,是否该写这个关键字  是跟你是否需要一直保持它的可见性,在开发中也可以省很多代码,例如JDK的Map中 的keySet和Values全局字段都使用了volatile,这个是为了保证每次来拿的时候都是最新的,类似这种用法还有很多。然后你说的cpu什么时候写主存这个我不知道,跟jdk的实现肯定也有关系,可以看下我这篇对volatile测试的文章,里面很好的测试了通过new大量的object 而cpu的处理速度显然快过内存,所以这个时候把数据写回了主存,但是如果你始终做i++运算,则工作内存的数据一致不会写入主存,程序也不会停止,http://my.oschina.net/ambitor/blog/661907

引用来自“Ambitor”的评论

volatile 会创建副本  但是每次读写的时候不会操作副本 都是操作主存,应该是第一种,还有一个要说明的是 现在的cpu处理能力而言,其实只要cpu不是被跑满的情况下 工作内存的变量也会马上写入主存,类似于volatile的意思,但前提是cpu有空。

引用来自“中山野鬼”的评论

前面一段不好说哦。后面一段我要提异议。现在的cpu快是快,但是现在的os策略是,把数据向片外存储器(就是主板上的内存)存储的时间尽量滞后,而不是马上写入“主存”。 需要volatile的地方,通常是进程之间(线程我不谈,哈,可以参照),对一个数据存在关联的情况。该写还得写。不该写的,相反不要写。一个数据该不该写volatile,和cpu快不快没关系,和用什么策略存储到片外存储器也没关系,和内部逻辑有关系。哈。

引用来自“Ambitor”的评论

java所有的变量都会拷贝副本到线程的,还有 我没有说一个数据该不该写volatile 跟cpu快是否有关,是否该写这个关键字  是跟你是否需要一直保持它的可见性,在开发中也可以省很多代码,例如JDK的Map中 的keySet和Values全局字段都使用了volatile,这个是为了保证每次来拿的时候都是最新的,类似这种用法还有很多。然后你说的cpu什么时候写主存这个我不知道,跟jdk的实现肯定也有关系,可以看下我这篇对volatile测试的文章,里面很好的测试了通过new大量的object 而cpu的处理速度显然快过内存,所以这个时候把数据写回了主存,但是如果你始终做i++运算,则工作内存的数据一致不会写入主存,程序也不会停止,http://my.oschina.net/ambitor/blog/661907

首先明确一个观点, volatile 不要和效率与速度挂钩,而是和内在设计的逻辑关联。如同用你的术语“可见性”,需要“可见性”的则一定要volatile ,无论跑起来快不快,慢不慢,不需要的,则一定不要。否则就不是快慢的问题了, 是逻辑时序错误的问题了。哈。

另外,java的东西,最好不要谈速度,如果c的东西,最好不要谈人脑的面向对象的思维。

这里针对java不要在这个层级谈效率,扩展的讨论一点,c里面,良好的设计,是“对象”不是动态"new"出来的。软件系统设计指标中支持多少个对象,在启动时就全部构造好。无非逻辑上的对象的生命周期,和存储这个对象空间的生命周期不同。如果要提高效率,这些对象摆放的位置都有说法。一种典型的方式是,当这些对象是依次访问的,那么就依次摆放;如果是间隔访问的,那么就需要根据访问的频率,保证下一次访问的对象不会与当前访问的对象在cache调度机制中存在冲突。(在效率上,曾经的实际工程开发,速度差异在1倍以上,比如无效率的500 ms完成,通过摆放位置的调整,可以在200ms完成)。但这些东西,也就c,或者c++玩一玩,java玩不了,也没必要玩。

很多业务系统,用c折腾是扯淡的事情,更应该用诸如java来完成,谈效率是更高一个策略层面的事情,减少访问动作,优化算法计算量上,而不是volatile这个层级。volatile第一,和效率没关系,第二,与volatile平级别的,涉及到cpu具体执行控制策略差异的处理,java的开发者也控制不了。哈。

引用来自“中山野鬼”的评论

引用来自“Ambitor”的评论

volatile 会创建副本  但是每次读写的时候不会操作副本 都是操作主存,应该是第一种,还有一个要说明的是 现在的cpu处理能力而言,其实只要cpu不是被跑满的情况下 工作内存的变量也会马上写入主存,类似于volatile的意思,但前提是cpu有空。

引用来自“中山野鬼”的评论

前面一段不好说哦。后面一段我要提异议。现在的cpu快是快,但是现在的os策略是,把数据向片外存储器(就是主板上的内存)存储的时间尽量滞后,而不是马上写入“主存”。 需要volatile的地方,通常是进程之间(线程我不谈,哈,可以参照),对一个数据存在关联的情况。该写还得写。不该写的,相反不要写。一个数据该不该写volatile,和cpu快不快没关系,和用什么策略存储到片外存储器也没关系,和内部逻辑有关系。哈。

引用来自“Ambitor”的评论

java所有的变量都会拷贝副本到线程的,还有 我没有说一个数据该不该写volatile 跟cpu快是否有关,是否该写这个关键字  是跟你是否需要一直保持它的可见性,在开发中也可以省很多代码,例如JDK的Map中 的keySet和Values全局字段都使用了volatile,这个是为了保证每次来拿的时候都是最新的,类似这种用法还有很多。然后你说的cpu什么时候写主存这个我不知道,跟jdk的实现肯定也有关系,可以看下我这篇对volatile测试的文章,里面很好的测试了通过new大量的object 而cpu的处理速度显然快过内存,所以这个时候把数据写回了主存,但是如果你始终做i++运算,则工作内存的数据一致不会写入主存,程序也不会停止,http://my.oschina.net/ambitor/blog/661907

首先明确一个观点, volatile 不要和效率与速度挂钩,而是和内在设计的逻辑关联。如同用你的术语“可见性”,需要“可见性”的则一定要volatile ,无论跑起来快不快,慢不慢,不需要的,则一定不要。否则就不是快慢的问题了, 是逻辑时序错误的问题了。哈。

另外,java的东西,最好不要谈速度,如果c的东西,最好不要谈人脑的面向对象的思维。

这里针对java不要在这个层级谈效率,扩展的讨论一点,c里面,良好的设计,是“对象”不是动态"new"出来的。软件系统设计指标中支持多少个对象,在启动时就全部构造好。无非逻辑上的对象的生命周期,和存储这个对象空间的生命周期不同。如果要提高效率,这些对象摆放的位置都有说法。一种典型的方式是,当这些对象是依次访问的,那么就依次摆放;如果是间隔访问的,那么就需要根据访问的频率,保证下一次访问的对象不会与当前访问的对象在cache调度机制中存在冲突。(在效率上,曾经的实际工程开发,速度差异在1倍以上,比如无效率的500 ms完成,通过摆放位置的调整,可以在200ms完成)。但这些东西,也就c,或者c++玩一玩,java玩不了,也没必要玩。

很多业务系统,用c折腾是扯淡的事情,更应该用诸如java来完成,谈效率是更高一个策略层面的事情,减少访问动作,优化算法计算量上,而不是volatile这个层级。volatile第一,和效率没关系,第二,与volatile平级别的,涉及到cpu具体执行控制策略差异的处理,java的开发者也控制不了。哈。

我明白你说的,有些观点说的也很对,譬如是否用volatile和效率、速度没关系,以及java该做它擅长的领域,But,有些观点 Not support,虽然与volatile级别的原理及操作 java开发者控制不了,但作为一个开发 应该尽可能知道它的深层次的原理、特性 在开发中才能规避一些问题,所以我说的那个当前cpu空闲时即便不谢volatile也会很快的写入主存,并没有强调和误导大家在什么时候用或者volatile,而只是把java中跟volatile和非volatile属性一些处理特性告诉大家。。
顶部