CAS

多线程进阶——狂神说java之JUC并发编程

霸气de小男生 提交于 2020-02-25 17:30:48
1、什么是JUC 学习可以参考:源码+官方文档 进行学习 文档地址: https://docs.oracle.com/javase/8/docs/api/ 首先我们看看什么是JUC 其次我们看看JUC都有哪些东西 于是我们可以总结下JUC可以分为五大类 1、同步工具类 2、lock类 3、原子类 4、集合相关类 5、Executor框架相关类 2、JUC入门前言——唠嗑 线程和进程 线程、进程,如果不能使用一句话说出来,说明技术不扎实! 进程:一个程序,QQ.exe Music.exe 程序的集合; 一个进程往往可以包含多个线程,至少包含一个! Java默认有几个线程? 2 个 mian、GC 线程:开了一个进程 Typora,写字,自动保存(线程负责的) 对于Java而言:Thread、Runnable、Callable Java 真的可以开启线程吗? 开不了,我们看看源码 public synchronized void start() { /** * This method is not invoked for the main method thread or "system" * group threads created/set up by the VM. Any new functionality added * to this method in the

Java的CAS与ABA问题

人走茶凉 提交于 2020-02-24 18:33:52
CAS操作是计算机底层的操作,对于内存中的某一个值V,提供一个旧值A和一个新值B,如果提供的旧值V和A相等就把B写入V,CAS操作是基于底层命令的,是原子性的操作 CAS在可以作为乐观锁的使用,每次操作不加锁,假设没有冲突,如果因为冲突失败就重试,直到成功为止 Java对CAS提供了很好的支持,如AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference等 CAS中存在一个经典的问题,即ABA问题:如果另一个线程修改V值假设原来是A,先修改成B,再修改回成A。当前线程的CAS操作无法分辨当前V值是否发生过变化 而对于ABA问题,Java也提供了很好的解决方案,AtomicStampedReference AtomicStampedReference在内部维护了一个Pair类,除了存储Reference外,也存储了当前数据对应的版本号,在执行compareAndSet方法时,会判断版本号是否一致,如果版本号不一致,则说明Reference已经发生过变化,在执行CAS操作时,实际更新的是Pair对象,因此Reference和版本号是同时原子更新的 Java同时提供了一个AtomicMarkableReference类,AtomicMarkableReference与AtomicStampedReference的API类似

我们常说的 CAS 自旋锁是什么

[亡魂溺海] 提交于 2020-02-23 03:27:57
https://www.cnblogs.com/fengzheng/p/9018152.html https://www.jianshu.com/p/f714c440d0cb CAS在jdk应用 ConcurrentHashMap1.7使用lock锁实现,1.8使用cas+synchronized CAS(Compare and swap),即比较并交换,也是实现我们平时所说的自旋锁或乐观锁的核心操作。 它的实现很简单,就是用一个预期的值和内存值进行比较,如果两个值相等,就用预期的值替换内存值,并返回 true。否则,返回 false。 保证原子操作 任何技术的出现都是为了解决某些特定的问题, CAS 要解决的问题就是保证原子操作。原子操作是什么,原子就是最小不可拆分的,原子操作就是最小不可拆分的操作,也就是说操作一旦开始,就不能被打断,直到操作完成。在多线程环境下,原子操作是保证线程安全的重要手段。举个例子来说,假设有两个线程在工作,都想对某个值做修改,就拿自增操作来说吧,要对一个整数 i 进行自增操作,需要基本的三个步骤: 1、读取 i 的当前值; 2、对 i 值进行加 1 操作; 3、将 i 值写回内存; 假设两个进程都读取了 i 的当前值,假设是 0,这时候 A 线程对 i 加 1 了,B 线程也 加 1,最后 i 的是 1 ,而不是 2。这就是因为自增操作不是原子操作

悲观锁与乐观锁

一世执手 提交于 2020-02-20 09:14:10
悲观锁 我悲观地认为,我只能通过加锁来解决高并发带来的数据错误问题。 思想: 为查询到的数据进行加锁,当A读这个数据的时候,B就无法读取数据,这解决了问题,但是要知道,加锁的时候消耗很多资源。 乐观锁 我乐观地认为,我可以不通过加锁的方式,就可以解决高并发带来的数据错误问题。 乐观锁的思想主要就是CAS,即Compare And Swap。 当要对查询到的数据进行操作之前,保存一份旧值,当需要修改数据的时候,进行比对,如果说跟原来一样,那就说明没人动过这份数据,可以继续进行,否则的话,说明数据有可能出现并发修改的数据错误,那就不再进行数据修改的操作。 以此来保证数据的正确性。 乐观锁的弊端即解决方案 CAS思想会引发ABA问题,即数据A经过修改变成了B,后面又变回了A,这对乐观锁处理并发问题是致命的,因为假如出现了ABA问题,CAS就会发现旧值和当前值相同,即会进行数据的修改,殊不知,数据已然被修改过。 一种比较典型的解决方案就是增加版本号字段,每次进行修改数据后,都让版本号+1,即使出现了ABA问题,版本号依旧是变的,从而能避免错误。 来源: CSDN 作者: 阳光大男孩!!! 链接: https://blog.csdn.net/weixin_43889841/article/details/104397333

How to use angularjs routing with CAS authentication redirect, or is angular just not usable?

为君一笑 提交于 2020-02-19 04:39:42
问题 My app usually uses the following for routing: http://angularapp.com/#/page=bannanas However, if the user is not authenticated, the user is redirected to a CAS login page, then after login, is redirected back to: http://angularapp.com/ Notice after redirect, CAS completely strips out the anchor/route "#/" since the anchor tag is not supported. https://issues.jasig.org/browse/CAS-1338 What is the best way around this? Is there a way I can do something like this: http://angularapp.com/?page

How to use angularjs routing with CAS authentication redirect, or is angular just not usable?

大兔子大兔子 提交于 2020-02-19 04:38:10
问题 My app usually uses the following for routing: http://angularapp.com/#/page=bannanas However, if the user is not authenticated, the user is redirected to a CAS login page, then after login, is redirected back to: http://angularapp.com/ Notice after redirect, CAS completely strips out the anchor/route "#/" since the anchor tag is not supported. https://issues.jasig.org/browse/CAS-1338 What is the best way around this? Is there a way I can do something like this: http://angularapp.com/?page

Spring Boot shiro+cas单点登录

夙愿已清 提交于 2020-02-16 23:27:53
Spring Boot shiro+cas单点登录 搭建Cas服务器 客户端 pom.xml 继承CasRealm application.yml UrlBean ShiroConfig 遗留问题??? 项目架构 2.1.11.RELEASE 项目源码 https://github.com/jsong93/Spring-Boot-shiro-cas-sso.git 根据SpringMVC项目改写 SpringMVC shiro+cas 单点登录 搭建Cas服务器 cas服务器搭建 md5+盐加密 客户端 pom.xml <?xml version="1.0" encoding="UTF-8"?> < project xmlns = " http://maven.apache.org/POM/4.0.0 " xmlns: xsi = " http://www.w3.org/2001/XMLSchema-instance " xsi: schemaLocation = " http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd " > < modelVersion > 4.0.0 </ modelVersion > < groupId > com.jsong.wiki </

并发编程之无锁

大憨熊 提交于 2020-02-16 21:03:53
并发编程之无锁 6.2 CAS与volatile 源码之LongAdder 6.8 Unsafe 6.2 CAS与volatile 其中的关键是compareAndSet,它的简称就是CAS(也有Compare And Swap的说法),它必须是原子操作。 注意 其实CAS的底层是lock cmpxchg指令(X86架构),在单核CPU和多核CPU下都能够保证【比较-交换】的原子性。 在多核状态下,某个核执行到带lock的指令时,CPU会让总线锁住,当这个核把此指令执行完毕,再开启总线。这个过程中不会被线程的调度机制所打断,保证了多个线程对内存操作的准确性,是原子的。 volatile 获取共享变量时,为了保证变量的可见性,需要使用volatile修饰。 它可以用来修饰成员变量和静态成员变量,他可以避免线程从自己的工作缓存中查找变量的值,必须到主存中获取它的值,线程操作volatile变量都是直接操作主存。即一个线程对volatile变量的修改,对另一个线程可见。 注意 : volatile仅仅保证了共享变量的可见性,让其它线程能够看到最新值,但不能解决指令交错问题(不能保证原子性) CAS必须借助volatile才能读取到共享变量的最新值来实现【比较并交换】的效果 为什么无锁效率高 无锁情况下,即使重试失败,线程始终在高速运行,没有停歇

转载---乐观锁和悲观锁

冷暖自知 提交于 2020-02-14 21:45:35
本文转载自链接: https://blog.csdn.net/qq_34337272/article/details/81072874 何谓悲观锁与乐观锁 乐观锁对应于生活中乐观的人总是想着事情往好的方向发展,悲观锁对应于生活中悲观的人总是想着事情往坏的方向发展。这两种人各有优缺点,不能不以场景而定说一种人好于另外一种人。 悲观锁 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。 乐观锁 总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。 两种锁的使用场景

CAS unSafe的使用

做~自己de王妃 提交于 2020-02-13 14:43:43
参考:https://www.cnblogs.com/duanxz/p/6097779.html package com.test; import sun.misc.Unsafe; import java.lang.reflect.Field; public class CASLearn { private static final Unsafe unsafe; private static final long nameOffset; private static final long valueOffset; private static final long intffset; //为了保证多线程间的可见性,所以声明为volatile 但是这个例子是单线程的 private volatile String name; private volatile long value; private volatile int age; static { try { //unsafe无法直接调用Unsafe.getUnsafe()去获取实例,这个方法只对可信任的类才能获取。 ///通过反射获取unsafe Field f = Unsafe.class.getDeclaredField("theUnsafe"); //Internal reference f.setAccessible