易语言 字段重复_使对易失性字段的操作原子化
易语言 字段重复
总览
易失性字段的预期行为是,它们在多线程应用程序中的行为应与在单线程应用程序中的行为相同。 禁止它们表现相同的方式,但是不能保证它们表现相同的方式。
Java 5.0+中的解决方案是使用AtomicXxxx类,但是这些类在内存(它们添加标头和填充),性能(它们添加引用和对其相对位置的控制很少)方面效率较低,从语法上讲,它们不是明确使用。
恕我直言,一个简单的解决方案,如果可变字段能够像预期的那样起作用,那么JVM必须在AtomicFields中支持的方式是当前JMM(Java内存模型)中所禁止的,但不能保证。
为什么要使字段
volatile字段的优点是,它们在线程中可见,并且某些避免重新读取它们的优化已被禁用,因此即使您没有更改它们,也始终要再次检查当前值。
例如不挥发
Thread 2: int a = 5;Thread 1: a = 6;
(后来)
Thread 2: System.out.println(a); // prints 5 or 6
具有挥发性
Thread 2: volatile int a = 5;Thread 1: a = 6;
(后来)
Thread 2: System.out.println(a); // prints 6 given enough time.
为什么不一直使用
易失的读写访问速度要慢得多。 当您写入易失性字段时,它将使整个CPU管道停顿下来,以确保已将数据写入缓存。 否则,即使在同一线程中,下一次读取该值也有可能会看到旧值(请参阅AtomicLong.lazySet(),这样可以避免停顿管道)
惩罚可能会慢10倍左右,您不想在每次访问时都这样做。
一个重要的限制是,即使您可能认为对字段的操作也不是原子的。 甚至比通常情况更糟,没有区别。 也就是说,它似乎可以工作很长时间甚至几年,并且由于偶然的更改(例如所用的Java版本),甚至对象加载到内存中而突然/随机中断。 例如,在运行程序之前加载了哪些程序。
例如更新值
Thread 2: volatile int a = 5;Thread 1: a += 1;
Thread 2: a += 2;
(后来)
Thread 2: System.out.println(a); // prints 6, 7 or 8 even given enough time.
这是一个问题,因为对a的读取和对a的写入是分别完成的,并且您可以获得竞争条件。 99%以上的时间它会表现出预期,但有时却不会。
你能为这个做什么?
您需要使用AtomicXxxx类。 这些将易失性字段包装为具有预期行为的操作。
Thread 2: AtomicInteger a = new AtomicInteger(5);Thread 1: a.incrementAndGet();
Thread 2: a.addAndGet(2);
(后来)
Thread 2: System.out.println(a); // prints 8 given enough time.
我有什么建议?
JVM具有一种按预期方式运行的方法,唯一令人惊讶的事情是您需要使用特殊的类来完成JMM不能保证的工作。 我建议更改JMM以支持当前由并发AtomicClasses提供的行为。
在每种情况下,单线程行为都是不变的。 没有看到竞争条件的多线程程序将表现相同。 区别在于,多线程程序不必查看竞争条件,而可以更改基本行为。
当前方法 | 建议语法 | 笔记 |
---|---|---|
x.getAndIncrement() | x ++或x + = 1 | |
x.incrementAndGet() | ++ x | |
x.getAndDecrment() | x–或x-= 1 | |
x.decrementAndGet() | -X | |
x.addAndGet(y) | (x + = y) | |
x.getAndAdd(y) | ((x + = y)-y) | |
x.compareAndSet(e,y) | (x == e?x = y,true:false) |
需要添加逗号语法 在其他语言中使用。 |
所有原始类型(例如布尔,字节,short,int,long,float和double)都可以支持这些操作。
可以支持其他赋值运算符,例如:
当前方法 | 建议语法 | 笔记 |
---|---|---|
原子乘法 | x * = 2; | |
原子减法 | x-= y; | |
原子分裂 | x / = y; | |
原子模量 | x%= y; | |
原子位移 | x << = y; | |
原子位移 | x >> = z; | |
原子位移 | x >>> = w; | |
原子和 | x&=〜y; | 清除位 |
原子或 | x | = z; | 设置位 |
原子异或 | x ^ = w; | 翻转位 |
有什么风险?
这可能会破坏依赖于这些操作的代码,这些代码有时会由于竞争条件而失败。
可能无法以线程安全的方式支持更复杂的表达式。 这可能会导致令人惊讶的错误,因为代码看起来像是正常的,但事实并非如此。 永远不会比当前状态更糟。
JEP 193 –增强挥发性
有一个JEP 193将此功能添加到Java。 一个例子是:
class Usage {volatile int count;int incrementCount() {return count.volatile.incrementAndGet();}
}
恕我直言,这种方法有一些限制。
- 语法是相当重要的变化。 更改JMM可能不需要更改Java语法,也可能不需要更改编译器。
- 这是一个不太通用的解决方案。 支持诸如体积+ =数量之类的操作可能很有用; 这些是双重类型。
- 开发人员要了解为什么他/她应该使用此代码而不是x ++ ,这会给开发人员带来更多负担;
我不相信使用更麻烦的语法可以更清楚地了解正在发生的事情。 考虑以下示例:
volatile int a, b;a += b;
要么
a.volatile.addAndGet(b.volatile);
要么
AtomicInteger a, b;a.addAndGet(b.get());
作为行,这些操作中的哪个是原子的。 他们都不回答,但是采用Intel TSX的系统可以使这些原子化,如果您要更改这些代码行中的任何行为,我都可以使a + = b; 而不是发明一种新的语法,该语法在大多数情况下会做同样的事情,但是可以保证一种语法,而不能保证另一种语法。
结论
如果JMM保证等效的单线程操作的行为符合多线程代码的预期,则可以消除使用AtomicInteger和AtomicLong的许多语法和性能开销。
可以通过使用字节码检测将该功能添加到Java的早期版本中。
翻译自: https://www.javacodegeeks.com/2014/07/making-operations-on-volatile-fields-atomic.html
易语言 字段重复
易语言 字段重复_使对易失性字段的操作原子化相关推荐
- 最大字段和_使对易失性字段的操作原子化
最大字段和 总览 易失性字段的预期行为是,它们在多线程应用程序中的行为应与在单线程应用程序中的行为相同. 禁止它们表现相同的方式,但是不能保证它们表现相同的方式. Java 5.0+中的解决方案是使用 ...
- 使对易失性字段的操作原子化
总览 易失字段的预期行为是,它们在多线程应用程序中的行为应与在单线程应用程序中的行为相同. 禁止它们表现相同的方式,但不能保证它们表现相同的方式. Java 5.0+中的解决方案是使用AtomicXx ...
- 易语言数据类型与c 对照,易语言利用自定义数据类型和数组. 制作键对值操作类/内存配置...
易语言利用自定义数据类型和数组. 制作键对值操作类/内存配置.版本 2 .支持库 spec .子程序 _临时子程序 .局部变量 test, classKeyValue .局部变量 局_取值方法2, ...
- 易语言java类_易语言面对对象编程
易语言面对对象编程---类的创建与使用 面对对象编程,可以说是当前最流行的编程方式,当前流行的面对对象的编程语言很多,如:C++.JAVA等等.易语言3.8版推出后,同样紧跟编程语言发展的方向,也开始 ...
- 易语言mysql验证_易语言MySql注册登录
用到的主要易语言命令: 连接MySql (, , , , ) 执行SQL语句 (, ) 取记录集 () 读字段值 (, , ) 释放记录集 () 断开MySql () 命令介绍: ①.连接MySql ...
- 易语言mysql乱码_分享一个解决MySQL写入中文乱码的方法
[编程语言:易语言] 之前有发帖请教过如何解决MySQL写入中文乱码的问题.但没人会,或者是会的人不想回答.搜索网上的答案并尝试很多次无效,所以当时就因为这个乱码问题搁浅了一个软件很多日子. 直到昨天 ...
- 易语言调用子程序_ c,易语言汇编调用子程序源码
.版本 2 .程序集 窗口程序集1 .子程序 __启动窗口_创建完毕 ' 调子程_Asm() ' 主要用于给某个子程序'自定义事件' 它等效于某官方支持库的'调用子程序()'命令 具体使用方法 可参照 ...
- 易语言lsp劫持_易语言网截插件修复源码
易语言网截插件修复源码.版本 2 .支持库 shell .支持库 eNetIntercept .子程序 _按钮1_被单击 写到文件 (取特定目录 (10) + "/lsp.bat" ...
- 易语言 python库_精易Python支持库 (1.1#1205版)发布啦!
精易Python支持库 (1.1#1205版) 本支持库提供了 6 种库定义数据类型,提供了 87 种命令. 支持库说明 该支持库为易语言调用并执行Python代码.文件提供了支持. 使用本支持库,可 ...
最新文章
- PHP的mysqli扩展
- 8月21日科技联播:支付宝转账遭骗可一键撤回,美团欲9月20日上市,估值不少于$600亿...
- (转)RTMP协议从入门到放弃
- Unity发布WebGl注意事项
- oracle初始化序列值,如何修改序列(Sequence)的初始值(START WITH)
- python如何执行代码漏洞_命令执行与代码执行漏洞原理
- 开公司的两个方向,要么把公司开成很赚钱,要么把公司做成很值钱
- django 集成个推_个推推送SDK集成过程及开发建议
- java如何构建图_如何从传递边构建子图?
- Silverlight 数据绑定(Binding)
- 虚拟机外接USB设备情况的vMotion问题
- java多线程-创建线程
- WEB前端使用SheetJS读写excel文件
- 洛谷OJ - P1156 - 垃圾陷阱
- OpenCL编程入门
- 网页显示无法解析服务器DNS地址,打开windows7系统下网页提示无法解析服务器的DNS地址怎么办...
- 高通modem启动过程_高通8953启动流程【转】
- makefile predefined variable $^ $@
- 面试题57:和为s的数字
- Kafaka报错:Creating topics with default partitions/replication factor are only supported in CreateTopi