原子操作

java开发:java多线程:原子类AtomicInteger和AtomicStampedReference使用详解

你。 提交于 2019-12-28 00:40:08
在上一节 java开发:乐观锁CAS机制 中我们说过CAS机制的原理,与及使用CAS会发生的ABA问题解决办法。 java中提供一些列的基本数据类型原子操作类用来实现操作基本数据类型时保证线程安全,其底层就是使用CAS机制实现的。 AtomicInteger 则是用来操作int类型的数据,保证线程安全。 什么是ABA问题呢?举个例子:比如说我的卡里有100大洋,此时有俩个线程同时去操作这100大洋,它们拿到的副本都是100。若线程2被阻塞了,线程1执行任务扣掉了50大洋,现在卡里剩50。正好我妈(线程3)此时刚好打给我50大洋,现在卡里的钱又变回了100。当线程2被唤醒后也执行扣款操作,扣掉50大洋,当它准备提交数据时比较旧的预期值和共享内存的实际值发现都是100,因此线程2也扣款成功,卡里只剩50大洋。。。想想就不对劲啊,我本来有100,我妈打给我50,我就取了50。不应该是剩100吗?这不害我白白损失了50大洋吗 final AtomicInteger atomicInteger = new AtomicInteger ( 100 ) ; ExecutorService service = Executors . newCachedThreadPool ( ) ; service . submit ( new Callable < Object > ( ) {

全面了解 Java 原子变量类

Deadly 提交于 2019-12-27 18:33:05
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 📦 本文以及示例源码已归档在 javacore 一、原子变量类简介 为何需要原子变量类 保证线程安全是 Java 并发编程必须要解决的重要问题。Java 从原子性、可见性、有序性这三大特性入手,确保多线程的数据一致性。 确保线程安全最常见的做法是利用锁机制( Lock 、 sychronized )来对共享数据做互斥同步,这样在同一个时刻,只有一个线程可以执行某个方法或者某个代码块,那么操作必然是原子性的,线程安全的。互斥同步最主要的问题是线程阻塞和唤醒所带来的性能问题。 volatile 是轻量级的锁(自然比普通锁性能要好),它保证了共享变量在多线程中的可见性,但无法保证原子性。所以,它只能在一些特定场景下使用。 为了兼顾原子性以及锁带来的性能问题,Java 引入了 CAS (主要体现在 Unsafe 类)来实现非阻塞同步(也叫乐观锁)。并基于 CAS ,提供了一套原子工具类。 原子变量类的作用 原子变量类 比锁的粒度更细,更轻量级 ,并且对于在多处理器系统上实现高性能的并发代码来说是非常关键的。原子变量将发生竞争的范围缩小到单个变量上。 原子变量类相当于一种泛化的 volatile 变量,能够 支持原子的、有条件的读/改/写操 作。 原子类在内部使用 CAS 指令(基于硬件的支持)来实现同步

线程安全问题

淺唱寂寞╮ 提交于 2019-12-27 15:13:58
本篇主要讲解 线程安全问题,演示什么情况下会出现线程安全问题,以及介绍了 Java内存模型 、volatile关键字 、CAS 等 ,最后感谢吴恒同学的投稿! 一起来了解吧!!  1. 如何会发生线程安全  运行如下程序: /** * @program: * @description: 多线程操作的对象 * @author: * @create: **/ public class MyCount { private int myCount = 0 ; public int getMyCount() { return myCount; } public void setMyCount(int myCount) { this.myCount = myCount; } @Override public String toString() { return "MyCount{" + "myCount=" + myCount + '}'; } }  创建线程 public class CountThread1 extends Thread{ private MyCount myCount ; private static Object synch = new Object(); public CountThread1( MyCount myCount) { this.myCount =

016_linux驱动之_原子操作

不打扰是莪最后的温柔 提交于 2019-12-26 11:34:23
原子操作 原子操作指的是在执行过程中不会被别的代码路径所中断的操作。 常用原子操作函数举例: atomic_t v = ATOMIC_INIT(0); //定义原子变量v并初始化为0 atomic_read(atomic_t *v); //返回原子变量的值 void atomic_inc(atomic_t *v); //原子变量增加1 void atomic_dec(atomic_t *v); //原子变量减少1 int atomic_dec_and_test(atomic_t *v); //自减操作后测试其是否为0,为0则返回true,否则返回false。 016_linux驱动之_原子操作引用,人间的写得挺好的 Linux内核驱动之原子变量 atomic_inc 原子操作 来源: CSDN 作者: 陆小果哥哥 链接: https://blog.csdn.net/xiaoguoge11/article/details/103708640

并发案例:如何保证统计变量的原子性

给你一囗甜甜゛ 提交于 2019-12-25 16:29:54
文章目录 引言 i++ 数据不一致案例分析 案例描述 问题分析 解决办法 AtomicInteger 原子类概述 案例描述 问题分析 延伸测试 启示录 引言 i++ 这个简单的语句,想必大家都不陌生,但是在多线程环境下,如果 i 是一个全局共享变量,那么它还能正确地按顺序累加吗?这就是本文要介绍的内容,如何保证统计变量的原子性。 其实, i++ 是由 “读取-修改-写入” 三个操作序列组成的复合操作,应该保证它们的原子性,否则就会出现数据不一致的情况。本文是根据笔者几年前的一篇旧文整理的,那时刚入行两年,并发编程经验几乎为零。 i++ 数据不一致案例分析 案例描述 笔者早年参与的一个项目中,需要对一个 http 请求请求结果进行统计,得到失败和成功的请求总数。一起合作的同事定义了两个全局共 来源: CSDN 作者: 毕小宝 链接: https://blog.csdn.net/wojiushiwo945you/article/details/103693060

事件驱动的数据管理

邮差的信 提交于 2019-12-24 14:12:48
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 一、微服务以及分布式数据管理中存在的问题 单体应用通常使用单个关系型数据库,由此带来的好处在于应用能够使用 ACID 事务,后者提供了重要的操作特性: 原子化: 原子粒度的更改 一致性: 数据库的状态始终保持一致 隔离: 并发执行的事务显示为串行执行 持久: 事务一旦提交就不会被撤销 如此,应用能够简单地开始事务、更改(插入、更新和删除)多行、以及提交事务。 使用关系型数据库的另一大好处是它支持 SQL。SQL 是一门丰富、可声明的和标准化的查询预约。用户能够轻松通过查询将多个表中的数据组合起来,然后 RDBMS 查询调度器决定执行查询的最优方法。用户不必关心底层细节,比如如何访问数据库。此外,由于所有的应用数据在一个数据库中,很容易查询。 然而,微服务架构中的数据访问变得复杂许多。每个微服务拥有的数据专门用于该微服务,仅通过其 API 访问。这种数据封装保证了微服务松散耦合,并且可以独立更新。但如果多个服务访问相同数据,架构更新会耗费时间、也需要所有服务的协调更新。 更糟糕的是,不同的微服务通常使用不同类型的数据库。现代应用存储和处理各种类型的数据,而关系型数据库并非总是好选择。对于一些使用场景,特定的 NoSQL 数据库能提供更方便的数据模型、更好的性能和可扩展性。譬如,服务使用 Elasticsearch

微服务实践(五):微服务的事件驱动数据管理

浪子不回头ぞ 提交于 2019-12-24 14:09:08
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 本系列七篇文章列表如下: 微服务实战(一):微服务架构的优势与不足 微服务实战(二):使用API Gateway 微服务实战(三):深入微服务架构的进程间通信 微服务实战(四):服务发现的可行方案以及实践案例 微服务实践(五):微服务的事件驱动数据管理 微服务实践(六):选择微服务部署策略 微服务实践(七):从单体式架构迁移到微服务架构 【编者的话】本文是使用微服务创建应用系列的第五篇文章。第一篇文章介绍了微服务架构模式,并且讨论了使用微服务的优缺点;第二和第三篇描述了微服务架构模块间通讯的不同方面;第四篇研究了服务发现中的问题。本篇中,我们从另外一个角度研究一下微服务架构带来的分布式数据管理问题。 1.1 微服务和分布式数据管理问题 单体式应用一般都会有一个关系型数据库,由此带来的好处是应用可以使用 ACID transactions,可以带来一些重要的操作特性: 原子性 – 任何改变都是原子性的 一致性 – 数据库状态一直是一致性的 隔离性 – 即使交易并发执行,看起来也是串行的 Durable – 一旦交易提交了就不可回滚 鉴于以上特性,应用可以简化为:开始一个交易,改变(插入,删除,更新)很多行,然后提交这些交易。 使用关系型数据库带来另外一个优势在于提供SQL(功能强大,可声明的,表转化的查询语言

使用Lua脚本通过原子减防止超卖

我怕爱的太早我们不能终老 提交于 2019-12-24 02:24:33
需求   双十二要搞一个一分钱门票抢购的活动。 分析   性能分析,抢购时会发生高并发,如果仅仅依靠Mysql数据库,有可能因为大量的请求频繁访问数据库造成服务器雪崩,所以考虑通过Redis减库存,最终的数据落地到DB中。   在高并发的情况下,还要考虑到超卖的问题,因而打算使用Lua脚本完成原子减的操作。   在这里,我们只针对减库存的操作进行分析。 实现   不使用原子操作,出现超卖的情况。第一步:先从redis中查出库存进行判断,第二步:如果库存>0,则进行减库存的操作。   代码实现: 1 // 第一步:从redis中查出库存 2 Integer stock = (Integer) RedisUtils.get("stock"); 3 4 // 第二步:如果库存>0,则进行减库存的操作 5 if (stock > 0) { 6 long spareStock = RedisUtils.decr("stock", 1); 7 System.out.println(getName() + "抢到了第" + spareStock + "件"); 8 } else { 9 System.out.println("库存不足"); 10 }   用多线程模拟并发请求:库存为500,创建505个线程去抢购。 1 for(int i =1;i<=505;i++){ 2 MyThread2

关于BSSE校正

你。 提交于 2019-12-23 23:13:43
本文转载自: http://blog.sina.com.cn/zhangsummer183 计算A、B分子间的弱相互作用能时,一般不能简单地通过E_interaction = E_AB - E(A) - E(B)来计算,因为E_AB能量相对于E(A) + E(B)的降低来自两方面,一方面是真实的A、B分子间的相互作用能,这是我们要求的;另一方面来自于A、B分子的基函数在复合物体系中重叠,相当于增大了复合物的基组而使E(AB)能量降低(严格来说前提是所用的理论方法是基于变分原理的),这个部分贡献如果也掺入E_interaction,则高估了相互作用能(即实际上结合能没有算出来的那么负),所以要去掉,它称为Basis Set Superposition Error(BSSE)。所以双分子的相互作用能应该表述为E_interaction = E_AB - E(A) - E(B) + E_BSSE。对于弱相互作用,E_BSSE所占E_interaction的比例往往不小,甚至超过它,如果不进行校正,可能正负号都不对。 基组越小,单体间相互作用越弱则E_BSSE越大。E_BSSE会随基组趋于完备而逐渐减小至0,给基组加上弥散函数能有效减小E_BSSE。对于氢键复合物,由于相互作用不算很弱,所以用了带弥散的中上等基组后,不做BSSE校正无妨。而pi-pi相互作用,即便用了aug-cc

Volatitle 修饰i i++线程安全吗

烂漫一生 提交于 2019-12-23 19:00:44
** Volatitle 修饰i i++线程安全吗 ** 首先 <分析Volatitle的问题> 1》Volatitle并不能解决非原子性操作的多线程安全问题。 2》Volatitle解决的是多线程共享变量间的可见性问题 3》使用Volatitle会增加性能开销。 其次 <分析i++的线程安全问题> 1》如果i是局部变量,则是线程安全的。因为局部变量中的每个线程都有自己的栈,它们之间不会发生冲突。 2》如果i是全局变量,则不是线程安全的。因为在全局变量中每个进程中的多个线程都可以访问到该变量。 本质上讲,并不是因为i是全局变量而导致她的线程不安全性。而是因为i++这个操作本身是非原子的。原子有不可分特性。如果是原子的话,即便多个线程都能访问到,它也是线性安全的。 3》i++这个过程执行了多个操作,首先读取i,然后值+1,最后将+1后的值写回i中。 最后 Java提供了java.util.concurrent.atomic 包来提供线程安全的基本类型包装类,但是使用synchronized或者AtomicXX系列的包装类时也会增加性能开销 来源: CSDN 作者: ancientidiot 链接: https://blog.csdn.net/ancientidiot/article/details/103660774