易语言 字段重复_使对易失性字段的操作原子化

易语言 字段重复

总览

易失性字段的预期行为是,它们在多线程应用程序中的行为应与在单线程应用程序中的行为相同。 禁止它们表现相同的方式,但是不能保证它们表现相同的方式。

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

易语言 字段重复

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/340206.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python爬虫数据可视化_适用于Python入门者的爬虫和数据可视化案例

本篇文章适用于Python小白的教程篇&#xff0c;如果有哪里不足欢迎指出来&#xff0c;希望对你帮助。 本篇文章用到的模块&#xff1a; requests,re,os,jieba,glob,json,lxml,pyecharts,heapq,collection 首先 本文我们的目的 抓取周杰伦的所有歌曲&#xff0c; 歌词&#xff0…

qt4 连接mysql_Qt4访问mysql 数据库的简单教程

编译问题&#xff1a;1、系统中安装有VC&#xff0c;所以头文件冲突手工修改makefile删除所有-I 加载VC头文件的项目2、mysql cannot find -llibmysql指定libmysql.a的路径-LQt 4 访问 mysql 数据库的简单教程云帆 2006/5/18因为目前无法使用linux&#xff0c; 所以 Qt 4.1.2 是…

python多个函数_什么是在Python中使用多个构造函数的干净的、pythonic的方法?

其实None对于“魔法”价值观来说要好得多&#xff1a;class Cheese(): def __init__(self, num_holes None): if num_holes is None: ... 现在&#xff0c;如果您想完全自由地添加更多参数&#xff1a;class Cheese(): def __init__(self, *args, **kwargs): #args -- tuple o…

Java 8和Java 14之间的新功能

从版本9开始&#xff0c;Java每6个月就会有新功能&#xff0c;因此很难跟踪这些新更改。 互联网上的大多数信息都描述了最近两个Java版本之间的变化。 但是&#xff0c;如果您的情况与我相似&#xff0c;则说明您使用的不是Java的最新版本&#xff0c;而是使用了较旧的Java版本…

mysql中如何卸载插件_Eclipse中如何卸载插件

很久没用Eclipse了&#xff0c;今天打开的时候&#xff0c;突然报Android开发插件需要更新。打开插件管理页面&#xff0c;更新Android插件&#xff0c;又提示和旧版本有冲突&#xff0c;心想只能卸载了重新安装了。找了半天没找到在哪下载&#xff0c;把Eclipse目录下的plugin…

python io_NumPy IO

NumPy IO Numpy 可以读写磁盘上的文本数据或二进制数据。 NumPy 为 ndarray 对象引入了一个简单的文件格式&#xff1a;npy。 npy 文件用于存储重建 ndarray 所需的数据、图形、dtype 和其他信息。 常用的 IO 函数有&#xff1a; load() 和 save() 函数是读写文件数组数据的两个…

Java 14:instanceof的模式匹配

Java 14引入了pattern Matching for instanceof &#xff08;另一种预览语言功能&#xff09; &#xff0c;从而消除了在使用instanceof时进行强制转换的需要。 例如&#xff0c;考虑以下代码&#xff1a; if (obj instanceof String) { String s (String) obj; System.out.pr…

centos7 mysql启动后端口_centos7 修改mysql5.7默认端口后启动异常

关闭selinux的方法有两种&#xff1a;临时关闭和永久关闭。查看selinux的状态&#xff1a;sestatus[root162-219-29-3 ~]# sestatusSELinux status: enabledSELinuxfs mount: /sys/fs/selinuxSELinux root directory: /etc/selinuxLoaded policy name: targetedCurrent mode: e…

computed怎么使用_Vuex 基本使用

简单介绍iPhone X 是 iPhone, Vuex 并不是 Vue.我们查看官方文档可以知道&#xff1a;Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。怎么理解呢&#xff1f;就拿我两位数的资产的银行卡来说吧&#xff0c;基本的存钱取钱&#xff0c;就是状态管理。怎么用我们将以一个简…

自然数 素数 质数_在Java中获取素数的无限列表

自然数 素数 质数一个常见的问题是确定数字的素因式分解。 蛮力方法是审判部门&#xff08; 维基百科 &#xff0c; 可汗学院 &#xff09;&#xff0c;但是如果必须考虑多个数字&#xff0c;这需要大量的浪费工作。 一种广泛使用的解决方案是Eratosthenes筛&#xff08; 维基…

mysql 大数据 join_MySQL JOIN算法原理

MySQL的JOIN相关操作&#xff0c;是通过“嵌套循环连接算法&#xff0c;NLJ”或者该算法的优化变体“块嵌套循环连接算法&#xff0c;BNLJ”来实现的。##### 嵌套循环连接算法两个表join时&#xff0c;可以简单理解为两层for循环&#xff0c;外层循环一般称作驱动表&#xff0c…

windows安装python3步骤_Windows下python3和python2安装与一起使用

一、python2和python3安装 2、安装步骤&#xff0c;直接双击运行&#xff0c;记得勾选添加环境变量就可以。图片1.png 3、安装已经选择了添加这个环境变量&#xff0c;所以不用再去配置。 如果没有勾选&#xff0c;得自己去设置。 鼠标右键我的电脑 -> 属性 -> 点击高级系…

mysql ondelete_MySQL on delete cascade语句

在本教程中&#xff0c;您将学习如何使用MySQL ON DELETE CASCADE引用操作来执行外键从多个相关表中删除数据。在上一个教程中&#xff0c;我们学习了如何使用单个DELETE语句从一个或多个相关表中删除数据。但是&#xff0c;MySQL提供了一种更为有效的方法&#xff0c;称为ON D…

您想了解的所有Throwable

本文是有关异常的教程。 但不是通常的一种。 其中有许多内容可以告诉您异常的含义&#xff0c;如何抛出异常&#xff0c;捕获异常&#xff0c;已检查异常与运行时异常之间的区别&#xff0c;等等。 没有必要了。 这对您来说也很无聊。 如果没有&#xff0c;那么请阅读其中的一本…

python构建二叉树_BinaryTree:学习二叉树的Python库

Python部落(python.freelycode.com)组织翻译&#xff0c;禁止转载&#xff0c;欢迎转发。简介&#xff1a; 您是否在为考试、作业或技术面试学习二叉树&#xff1f; Binarytree是一个Python库&#xff0c;它通过一个简单的API生成二叉树&#xff0c;可以进行检查和操作。它让您…

mysql union as 注入_sql注入入门 之 mysql 常规注入 [ union方式 ]

1,常规数字型 mysql 实例注入点,如下:1https://www.vuln.com/md_materia_profile_view.php?viewid22,依旧先尝试下经典的单引号,如下,虽然没暴露出明显的数据库报错信息,但我们发现,此时返回的页面已经异常了,经验判断,十有八九是个注入点,先不管那么多,我们继续1https://www.…

gradle docker_带有Gradle的Docker容器分为4个步骤

gradle docker您是否需要通过Java Web应用程序创建Docker映像&#xff1f; 您在使用Gradle吗&#xff1f; 如果是这样&#xff0c;那么您距Docker nivana仅4步之遥。 对于此示例&#xff0c;我将使用一个简单的Spring Boot应用程序。 您可以在我的名为galoshe的Github存储库中…

mysql数据库连接关闭_解决mysql数据库连接自动关闭问题

MySQL是一个小型关系型数据库管理系统&#xff0c;由于MySQL体积小、速度快、总体拥有成本低&#xff0c;尤其是开放源码这一特点&#xff0c;许多中小型网站为了降低网站总体拥有成本而选择了MySQL作为网站数据库。关于mysql自动关闭服务的现象&#xff0c;可以通过mysql服务器…

python socket编程_Python学习记录-socket编程

1. OSI七层模型详解2. Python socket 什么是 Socket? Socket又称”套接字”&#xff0c;应用程序通常通过”套接字”向网络发出请求或者应答网络请求&#xff0c;使主机间或者一台计算机上的进程间可以通讯。 Python 提供了两个级别访问的网络服务&#xff1a; 低级别的网络服…

REST / HTTP方法:POST与PUT与PATCH

每个HTTP请求都包含一个方法 &#xff08;有时称为verb &#xff09;&#xff0c;该方法指示对标识的资源执行的操作。 在构建RESTful Web服务时&#xff0c;HTTP方法POST通常用于创建资源&#xff0c;而PUT用于资源更新。 尽管在大多数情况下这很好&#xff0c;但使用PUT进行…