CAS

CAS解析

喜夏-厌秋 提交于 2020-02-06 10:51:47
CAS:compare and swap,也有的叫做 compare and set;意思都差不多,翻译过来就是比较并交换或者比较并设值。 CAS包含三个值,内存地址(V),预期值(A),新值(B)。先比较内存地址的值和预期的值是否相等,如果相等,就将新值赋在内存地址上,否则,不做任何处理。这种是乐观锁的思想。 源码解析 CAS操作在JUC中大量用到,在解析AQS那章中,我们也有提到。再回头看一下AQS中CAS的操作 protected final boolean compareAndSetState(int expect, int update) { return unsafe.compareAndSwapInt(this, stateOffset, expect, update); } 这里是对AQS中state变量进行的CAS操作,要知道,很多同步类都是通过这个变量来实现线程安全的,所以在AQS中,首先要保证对state的赋值是线程安全的。 在java中,不论什么操作,只要他还是在Java api级别,就不能保证他一定是线程安全的,除非这个操作调用系统资源来支持。这里保证state线程安全是通过unsafe中的compareAndSwapInt方法来实现的,里面的参数stateOffset就是内存地址(V),expect是预期值(A),新值(B)。在unsafe中

java基础面试题

一曲冷凌霜 提交于 2020-02-04 11:37:35
1.synchronized的底层原理? synchronized底层原理,是跟JVM指令和monitor有关,你如果用到了synchronized关键字,在底层的JVM指令中,会有monitorenter和monitorexit两个指令, 每个对象都有一个关联的monitor,如果要对一个对象加锁,那么必须获取这个对象关联的monitor的lock锁, monitor的锁是支持可重入的,里边会有一个一个计数器,第一次加锁时候,会把计数器加1,变成1,第二次时候,会在加一,变成2,这样就是可重入加锁,这个时候,如果其他线程来获取这个对象的锁,发现monitor的计数器不为0,意味着别人加锁了。然后这个线程就会进入block阻塞状态,什么都干不了,就是等着获取锁,如果程序执行出了synchronized的范围,会执行monitorexit指令,会对线程获取锁的那个对象的monitor计数器减1,如果有多次重入加锁就会对应多次减1,知道最后,计数器是0,然后后边阻塞的线程就可以获取锁了,同样只有一个线程可以获取到锁。 2. CAS锁的理解以及实现原理 CAS:compare and set AtomicInteger.incrementAndGet(); 线程在操作之前,会先去读取一下变量的旧值,然后把它加一,尝试赋值给变量,赋值之前会检查一下变量的值和之前获取到的值是否一致,如果一致

谈谈线程安全与锁优化

佐手、 提交于 2020-02-04 02:46:02
写在前面 本文是作为阅读《深入理解Java虚拟机》第13章线程安全与锁优化的读书笔记; 线程安全是以多个线程之间存在共享对象为前提的。它并不是一个非黑即白的问题。Brian Goetz 曾就线程安全的“安全程度” 按以下由强至弱做了划分: 不可变;这类对象不需要进行任何线程安全的保障措施,只要这个对象被构建出来,其外部的可见状态永远也不会改变。如果共享数据是一个基本数据类型,那么只要在定义时使用 final 关键字修饰它,就可以保证它是不可变的。如果共享数据是一个对象类型,那就需要保证对象的行为不会对其状态产生任何影响才行,像 String 类的对象。 绝对线程安全;这类的划分的定义和不可变很像,但不可变更加的纯粹,简单。如果一个对象要是绝对线程安全的,那么需要保证多个线程中,对该对象的各种行为调用组合,都会得到想要的结果。举个例子来说, Vector 是线程安全的,但并不是绝对线程安全,比如,在一个线程对一定容量大小的 Vector 进行 remove 操作,另一线程进行 get 操作,最终,你会得到一个数组越界异常,这并不是我们想要的结果。其实,绝对线程安全是一种很苛刻的条件,所以,Java 中所讲的线程安全,通常指的是下面的相对线程安全。 相对线程安全;针对单个对象的单独操作是线程安全的。像上面 Vector 的 get 、remove 等操作。 线程兼容

【架构师技巧分享】程序员面试美团:面试官突然问Java “锁”你应该怎么回答?

天涯浪子 提交于 2020-02-02 18:02:15
【架构师技巧分享】程序员面试美团:面试官突然问Java “锁”你应该怎么回答? Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率。本文旨在对锁相关源码(本文中的源码来自JDK 8)、使用场景进行举例,为读者介绍主流锁的知识点,以及不同的锁的适用场景。 Java中往往是按照是否含有某一特性来定义锁,我们通过特性将锁进行分组归类,再使用对比的方式进行介绍,帮助大家更快捷的理解相关知识。下面给出本文内容的总体分类目录: 1.乐观锁 VS 悲观锁 乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度。在Java和数据库中都有此概念对应的实际应用。 先说概念。对于同一个数据的并发操作,悲观锁认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,确保数据不会被别的线程修改。Java中,synchronized关键字和Lock的实现类都是悲观锁。 而乐观锁认为自己在使用数据时不会有别的线程修改数据,所以不会添加锁,只是在更新数据的时候去判断之前有没有别的线程更新了这个数据。如果这个数据没有被更新,当前线程将自己修改的数据成功写入。如果数据已经被其他线程更新,则根据不同的实现方式执行不同的操作(例如报错或者自动重试)。 乐观锁在Java中是通过使用无锁编程来实现,最常采用的是CAS算法

并发编程(3)--原子操作CAS

和自甴很熟 提交于 2020-02-01 12:50:20
3 、原子操作 CAS Atom (不可分割) 什么是原子操作?如何实现原子操作? syn 基于阻塞的锁的机制, 1 、被阻塞的线程优先级很高, 2 、拿到锁的线程一直不释放锁怎么办? 3 、大量的竞争,消耗 cpu ,同时带来死锁或者其他安全。 CAS 的原理 CAS(Compare And Swap) ,指令级别保证这是一个原子操作。利用现代处理器都支持的CAS指令,循环这个指令直到成功为止。 三个运算符: 一个内存地址 V ,一个期望的值 A ,一个新值 B 基本思路:如果地址 V 上的值和期望的值 A 相等,就给地址 V 赋给新值 B ,如果不是,不做任何操作。 循环(死循环,自旋)里不断的进行 CAS 操作 CAS 的问题 1.ABA问题,可以用版本号来解决 A--- 》 B---- 》 A ,版本号 : A1 àB2-àA3 2.开销问题 CAS 操作长期不成功, cpu 不断的循环, 3.只能保证一个共享变量的原子操作 因为一个内存地址只会指向一个变量,可以使用下面的 AtomicReference Jdk 中相关原子操作类的使用 对于不太适合使用synchronize关键字的时候 ,比如简单的数字相加操作,用锁不方便,笨重的时候 Jdk中相关原子操作类的使用 更新基本类型类:AtomicBoolean,AtomicInteger,AtomicLong 更新数组类

阅读笔记(五)多线程无锁的C++实现《Lock-Free Data Structures》

只谈情不闲聊 提交于 2020-02-01 11:52:34
1. 前言   本文介绍使用C++实现多线程中无锁算法的实现和优化过程。 2. 无锁&CAS   在多线程程序中,加锁是一种必要的手段,由于保证数据操作的正确性(原子性)。但是这也在很多时候带来了性能的极度下降,因为所有共享数据的操作均需要加锁,有些时候会严重影响性能,比如当读键盘或者一些较慢的I/O操作时,锁会延误了其他线程的操作。更糟糕的是,不当操作可能会带来死锁。   首先介绍最经典的无锁操作:compare-and-swap (CAS) 操作。CAS比较内存地址是否满足要求,若成功则写入value,这整个过程是原子性的。 template < class T > bool CAS ( T * addr , T expected , T value ) { if ( * addr == expected ) { * addr = value ; return true ; } return false ; } 3. WRRM Map   WRRM (Write Rarely Read Many) 是一种常见的情况,即大多数读、很少写的操作。我们可以通过std::map或者std::unordered_map来实现( 区别见这里 ),单同时asso_vector也是一个比较好的选择。在这里我们用 Map<key, value> 代替,具体实现可以根据需求修改

JUC中的原子操作类及其原理

百般思念 提交于 2020-01-31 03:46:37
  昨天简单的看了看Unsafe的使用,今天我们 看看 JUC中的原子类是怎么使用Unsafe的,以及分析一下其中的原理! 一.简单使用AtomicLong   还记的上一篇博客中我们使用了volatile关键字修饰了一个int类型的变量,然后两个线程,分别对这个变量进行10000次+1操作,最后结果不是20000,现在我们改成AtomicLong之后,你会发现结果始终都是20000了!有兴趣的可以试试,代码如下 package com.example.demo.study; import java .util.concurrent.atomic.AtomicLong; public class Study0127 { // 这是一个全局变量,注意,这里使用了一个原子类AtomicLong public AtomicLong num = new AtomicLong(); // 每次调用这个方法,都会对全局变量加一操作,执行10000次 public void sum() { for ( int i = 0; i < 10000; i++ ) { // 使用了原子类的incrementAndGet方法,其实就是把num++封装成原子操作 num.incrementAndGet(); System.out.println( "当前num的值为num= "+ num); } }

01-022【jvm】CAS与原子类ABA问题

旧城冷巷雨未停 提交于 2020-01-30 17:19:55
CAS即Compare and Swap ,体现了乐观锁思想 CAS CAS是什么? CAS:即Compare-And-Swap,它是一条CPU并发原语,它的功能是判断内存某个位置的值是否为预期值,如果是则更改为新的值,这个过程是原子的。 获取共享变量时,为了保证该变量的可见性,需要使用volatile修饰。结合CAS和volatile可以实现无锁并发,适用于竞争不激烈、多核CPU的场景下。 底层原理 CAS并发原语 体现在java语言中就是sun.misc. UnSafe类 中的各个方法。调用UnSafe类中的CAS方法,JVM会帮我们实现CAS汇编指令。这是一种 完全依赖于硬件 的功能,通过它实现了原子操作。再次强调,由于CAS是一种系统原语,原语属于操作系统用语范畴,是由若干条指令组成的,用于完成某个功能的一个过程,并且 原语的执行必须是连续的,在执行过程中不允许被中断 ,也就是说 CAS是一条CPU的原子指令,不会造成所谓的数据不一致的问题 。 以AtomicInteger为例,源码 源码 public final int getAndIncrement ( ) { return unsafe . getAndAddInt ( this , valueOffset , 1 ) ; } 那么UnSafe类是什么? 在rt.jar中,jdk的基础类,其中方法均由native修饰

java多线程之CAS操作AtomicInteger,AtomicIntegerArray,AtomicReference等原子操作类详解

余生长醉 提交于 2020-01-30 10:06:46
原子操作是什么 原子操作即不可被中断(分割)的一个或一系列操作,如对于A,B两个操作,如果一个线程操作A,若另一个线程执行B操作时,要么将B执行到结束,要么完全不让B执行,此时对于A和B来说,就是原子的。 悲观锁和乐观锁 如 synchronized 就是悲观锁,解决多线程并发问题,以保证事务的完整性。其是基于阻塞的锁机制,如果有一个线程拥有锁后,访问该资源的其他线程就需要阻塞等待,直到获得锁的线程释放锁。 CAS操作即是乐观锁,每个线程都可以访问,只有在提交数据的时候检查是否违反了数据的完整性,即每次都尝试去完成某个操作,如果冲突和造成操作失败,就循环重试,直到操作成功为止。 使用 synchronized 会引出很多问题,如:获得锁的线程一直不释放锁;大量线程竞争资源,可能会造成死锁;被阻塞的线程可能优先级很高却一直无法获取锁。 因此实现原子操作可使用CAS指令。 CAS CAS 即Compare and Swap,比较并交换。每个CAS操作过程都包括三个运算符: 内存地址V、期望值A、新的值B 如果操作的时候地址V上的值等于期望的值A,则将地址V上的值更新为B,否则不做任何操作,但要返回原值。循环CAS就是不断的进行CAS操作直到操作成功。可防止内存中共享变量出现脏读脏写的问题。 CAS是通过硬件CPU和内存,利用CPU的多处理能力实现硬件层面的阻塞

CAS Authentication Library for CodeIgniter

做~自己de王妃 提交于 2020-01-30 08:34:25
问题 I am trying to implement CAS authentication in a CodeIgniter application though I cannot find if there are any libraries currently set up for it. I am managing by just including the class and adding in a few dirty fixes though if anyone knows of a proper library I think it would be a cleaner solution. I have been looking through a range of posts on here as well as all over Google but seem to be coming up short on what I need. The only place of any relevance is a post on VCU Libraries but that