原子操作

高并发课程笔记

放肆的年华 提交于 2019-12-23 12:10:05
高并发课程笔记 (一) 第一课 synchronized 线程重入 (一)第二课 是否可以在同步方法运行期间,插入一个非同步方法? 脏读问题 一个同步方法可以调用另一个同步方法吗? (一)第三课 一个同步方法可以调用另一个同步方法吗? synchronized 方法异常 volatile 关键字 volatile 的问题 (一)第四课 原子类 synchronized 优化 避免将锁定对象的引用变成另外的对象 不要用字符串常量作为锁定对象 (一)第五六课 (二) 第一二三课 ReenTrantLock ReenTrantLock与synchronized的区别 trylock() lockInterruptibly 公平锁 生产者消费者模式 (二)第四课 线程局部变量 (三)Java的并发容器类 (三)第一二课 线程的单例模式 创建线程安全的单例模式, 高并发容器开头 火车站卖票第一版 火车站卖票第二版(Vector容器) 火车站卖票第三版(LinkedList +synchronized) 火车站卖票第四版(并发容器 ConcurrentLinkedQueue) (三)第三四课 并发容器 Concurrent 类的Map 写时复制容器 ConcurrentLinkedQueue LinkedBlockingQueue ArrayBlockingQueue DelayQueue

JUC 基础内容概述

半城伤御伤魂 提交于 2019-12-23 10:50:29
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> Concurrent Programming in Java 的作者 Doug Lea 编写了一个极其优秀的、免费的并发实用程序包,它包括并发应用程序的锁、互斥、队列、线程池、轻量级任务、有效的并发集合、原子的算术操作和其它基本构件。我们一般称这个包为 J.U.C。 1. JUC概况 以下是Java JUC包的主体结构: Atomic : AtomicInteger Locks : Lock, Condition, ReadWriteLock Collections : Queue, ConcurrentMap Executer : Future, Callable, Executor Tools : CountDownLatch, CyclicBarrier, Semaphore 2. 原子操作 多个线程执行一个操作时,其中任何一个线程要么完全执行完此操作,要么没有执行此操作的任何步骤,那么这个操作就是原子的。出现原因: synchronized的代价比较高。 以下以AtomicInteger为例: int addAndGet(int delta):以原子方式将给定值与当前值相加。 实际上就是等于线程安全版本的i =i+delta操作。 boolean compareAndSet(int expect,

redis

故事扮演 提交于 2019-12-22 10:51:58
高性能存储,数据都在内存中。所以高频的小数据都可以往里放等等。 数据类型分为list、set、zset、hash IOPS基本是HDD的上千倍 所有的操作都是原子的。单个操作是原子性的,多个操作也支持事务,即原子性 支持五种数据类型。string、hash、list、set、zset(有序集合) string set & get HASH(散列表) set & get & hmset 来源: CSDN 作者: CrankyPants 链接: https://blog.csdn.net/CrankyPants/article/details/103646412

线程安全—可见性和有序性

馋奶兔 提交于 2019-12-21 18:57:04
在并发编程中,需要处理的两个关键问题: 线程之间如何通信 以及 线程之间如何同步 。 通信 是指线程之间以或者机制交换信息,java的并发采用的是共享内存模型,线程之间共享程序的公共状态,通过读写内存中的公共状态进行隐式通信。 同步 是是指程序中用于控制不同线程间操作发生相对顺序的机制。 最开始首先应该知道计算机中的 缓存 在其中起的作用 CPU Cache(高速缓存):由于计算机的存储设备与处理器的处理设备有着几个数量级的差距,所以现代计 算机都会加入一层读写速度与处理器处理速度接近相同的高级缓存来作为内存与处理器之间的缓冲,将运 算使用到的数据复制到缓存中,让运算能够快速的执行,当运算结束后,再从缓存同步到内存之中,这 样,CPU就不需要等待缓慢的内存读写了。 主(内)存:一个计算机包含一个主存,所有的CPU都可以访问主 存,主存比缓存容量大的多(CPU访问缓存层的速度快于访问主存的速度!但通常比访问内存寄存器的速度还是要慢点) 运作原理:通常情况下,当一个CPU要读取主存(RAM - Main Mernory)的时候,他会将主存中的数据读 取到CPU缓存中,甚至将缓存内容读到内部寄存器里面,然后再寄存器执行操作,当运行结束后,会 将寄存器中的值刷新回缓存中,并在某个时间点将值刷新回主存。 为什么需要CPU Cache? 答:CPU 的频率太快了,快到主存跟不上

Java并发编程之原子操作类

喜你入骨 提交于 2019-12-21 14:18:56
什么是原子操作类 当更新一个变量的时候,多出现数据争用的时候可能出现所意想不到的情况。这时的一般策略是使用synchronized解决,因为synchronized能够保证多个线程不会同时更新该变量。然而,从jdk 5之后,提供了粒度更细、量级更轻,并且在多核处理器具有高性能的原子操作类。因为原子操作类把竞争的范围缩小到单个变量上,这可以算是粒度最细的情况了。 原子操作类相当于泛化的volatile变量,能够支持原子读取-修改-写操作。比如AtomicInteger表示一个int类型的数值,提供了get和set方法,这些volatile类型的变量在读取与写入上有着相同的内存语义。原子操作类共有13个类,在java.util.concurrent.atomic包下,可以分为四种类型的原子更新类:原子更新基本类型、原子更新数组类型、原子更新引用和原子更新属性。 下面介绍这各种原子操作类 1 原子更新基本类型:使用原子方式更新基本类型 AtomicBoolean:原子更新布尔变量 AtomicInteger:原子更新整型变量 AtomicLong:原子更新长整型变量 2 原子更新数组:通过原子更新数组里的某个元素 AtomicIntegerArray:原子更新整型数组的某个元素 AtomicLongArray:原子更新长整型数组的某个元素 AtomicReferenceArray

CAS操作原理分析

旧城冷巷雨未停 提交于 2019-12-20 21:25:02
一、CAS简单介绍 CAS:Compare and Swap, 翻译成比较并交换。 java.util.concurrent包中借助CAS实现了区别于synchronouse同步锁的一种乐观锁。synchronouse是一种悲观锁,它会导致其他所有需要锁的线程挂起。 二、CAS原理 CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。 CAS采用的是一种非阻塞算法(nonblocking algorithms),一个线程的失败或者挂起不应该影响其他线程的失败或挂起的算法。 CAS通过调用JNI的代码实现Java的非阻塞算法。其它原子操作都是利用类似的特性完成的。JNI:Java Native Interface为JAVA本地调用,允许java调用其他语言。 拿AtomicInteger来举例, private volatile int value; 1.它有个volatile的成员变量 value,通过volatile关键字来保证多线程间数据的可见性的。 所以在没有锁的机制下可能需要借助volatile原语,保证线程间的数据是可见的(共享的)。这样才获取变量的值的时候才能直接读取。 public final int get() { return value; } 2.通过CAS操作来实现+1操作的

JAVA CAS原理深度分析

点点圈 提交于 2019-12-20 02:59:47
CAS CAS:Compare and Swap, 翻译成比较并交换。 java.util.concurrent包中借助CAS实现了区别于synchronouse同步锁的一种乐观锁。 本文先从CAS的应用说起,再深入原理解析。 CAS应用 CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。 非阻塞算法 (nonblocking algorithms) 一个线程的失败或者挂起不应该影响其他线程的失败或挂起的算法。 现代的CPU提供了特殊的指令,可以自动更新共享数据,而且能够检测到其他线程的干扰,而 compareAndSet() 就用这些代替了锁定。 拿出AtomicInteger来研究在没有锁的情况下是如何做到数据正确性的。 private volatile int value; 首先毫无以为,在没有锁的机制下可能需要借助volatile原语,保证线程间的数据是可见的(共享的)。 这样才获取变量的值的时候才能直接读取。 public final int get() { return value; } 然后来看看++i是怎么做到的。 public final int incrementAndGet() { for (;;) { int current = get(); int next = current

JAVA CAS原理深度分析

泪湿孤枕 提交于 2019-12-20 02:59:07
参考文档: http://www.blogjava.net/xylz/archive/2010/07/04/325206.html http://blog.hesey.net/2011/09/resolve-aba-by-atomicstampedreference.html http://www.searchsoa.com.cn/showcontent_69238.htm http://ifeve.com/atomic-operation/ http://www.infoq.com/cn/articles/java-memory-model-5 java.util.concurrent包完全建立在CAS之上的,没有CAS就不会有此包。可见CAS的重要性。 CAS CAS:Compare and Swap, 翻译成比较并交换。 java.util.concurrent包中借助CAS实现了区别于synchronouse同步锁的一种乐观锁。 本文先从CAS的应用说起,再深入原理解析。 CAS应用 CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。 非阻塞算法 (nonblocking algorithms) 一个线程的失败或者挂起不应该影响其他线程的失败或挂起的算法。 现代的CPU提供了特殊的指令

CAS--JAVA为什么选择它,如何解析并实现它?

纵饮孤独 提交于 2019-12-20 02:44:38
这边参考的是: A-B-A问题: https://hesey.wang/2011/09/resolve-aba-by-atomicstampedreference.html CAS解析: https://blog.csdn.net/v123411739/article/details/79561458 https://www.cnblogs.com/onlywujun/articles/3529572.html 牛人: http://ifeve.com/ 首先CAS 是是什么? Compare and Swap,是比较并交换的意思。 CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。 它是一种非阻塞型的算法,一个线程的失败或者挂起不应该影响其他线程的失败或挂起的算法。 现代的CPU提供了特殊的指令,可以自动更新共享数据,而且能够检测到其他线程的干扰,而 compareAndSet() 就用这些代替了锁定。 这边拿AtomicInteger来研究在没有锁的情况下是如何做到数据正确性的。 private volatile int value; 在没有锁的机制下可能需要借助volatile原语,保证线程间的数据是可见的(共享的)。 这样在获取变量的值的时候才能直接读取。 public final int

Fence和非原子操作的ordering

*爱你&永不变心* 提交于 2019-12-16 10:24:13
除了在原子操作中标记memory ordering外,还可以单独使用fence指定memory ordering。Fence是全局的操作,它影响所执行线程中其他原子操作的ordering。 123456789101112131415 atomic<bool> x,y;atomic<int> z;void () { x.store(true,memory_order_relaxed); atomic_thread_fence(memory_order_release); y.store(true,memory_order_relaxed);}void read_y_then_x() { while(!y.load(memory_order_relaxed)); atomic_thread_fence(memory_order_acquire); if(x.load(memory_order_relaxed)) ++z;} 上面的代码中,如果没有显式的fence, z 的值是不确定的。 关于fence,有几个synchronizes-with规则: 如果acquire操作能读取到位于release fence后面store的写入的值,那么这个fence synchronizes-with acquire操作。 如果位于acquire