多线程01-CAS (CompareAndSwap)
1.基本概念
原子性是不可中断的最小操作;在Java中,一般通过加锁或者自旋CAS方式来确保原子操作;
而CAS(compareAnd swap)作为Java中常用的保证原子性的手段,JDK1.5之后就提供了相关的操作类,java.util.concurrent.atomic包中的工具类;
CAS概念:CAS操作需要两个值,旧值(预期的操作之前的值)和新值,先将旧值进行比较,如果旧值没有发生变化,则进行操作,如果旧值变化则不进行任何操作
2.常用来解释CAS的一个案例:
public class CASTest {
private int i = 0;
private AtomicInteger ai = new AtomicInteger();
private static final Integer NUM = 10;
private static CountDownLatch latch = new CountDownLatch(NUM);
public static void main(String[] args) throws InterruptedException {
final CASTest t = new CASTest();
for(int i =0 ; i < NUM ; i++){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for(int j = 0 ; j < 100 ; j++){
t.count();
// t.safeCount();
}
latch.countDown();
}
});
thread.start();
}
latch.await();
System.out.println("======= over ======="+t.i);
}
public void count(){
i ++ ;
}
public void safeCount(){
for(;;){
int i = ai.get();
boolean b = ai.compareAndSet(i, i++);
if( b ){
break ;
}
}
}
}
理想的结果是1000,但是非CAS的结果总是会有差异,而safeCount 采用的是CAS的方式进行原子操作;
3.CAS 操作存在的问题和解决方案
1.ABA问题
问题描述:首先,假设一个变量经过A=>B=>A的变化过程,一个线程进行,获取到操作前的值为A,按照上面的概念这个线程获取到的旧值A,和这个变量进行变化后的现在的新值A是一样的。如果进行CAS自旋操作无疑是有问题的。
解决方案:JDK中atomic包中提供了,AtomicStampedReference 类,提供了更完善的方法。通过增加标志,来对旧值进行判断。

2.循环时间长开销大
问题描述:当一个线程修改的值,被其他线程再次修改后,自旋旧值比对长时间无法获取成功,导致资源的浪费;
解决方案:JVM中提供了puse指令可以解决这种问题;
3.只能保证一个变量的原子操作
问题描述:如题
解决方案:通过将多个变量封装成一个对象,通过atomic包中的AtomicReference类来进行解决;
参考图书《java并发编程艺术》(ps:这个随笔就是看书笔记)
最后,
多线程01-CAS (CompareAndSwap)的更多相关文章
- Java多线程| 01 | 线程概述
Java多线程| 01 | 线程概述 线程相关概念 进程与线程 进程:进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是操作系统进行资源分配与调度的基本单位.可以把进程简单的理解 ...
- Java 多线程 - 原子操作AtomicInteger & CAS(Compare-and-Swap)
原子类简介:https://www.cnblogs.com/stephen0923/p/4505902.html AtomicInteger 介绍: https://yuwenlin.iteye.co ...
- Java多线程:CAS与java.util.concurrent.atomic
锁的几种概念 悲观锁 总是假设最坏的情况,每次获取数据都认为别人会修改,所以拿数据时会上锁,一直到释放锁不允许其他线程修改数据.Java中如synchronized和reentrantLock就是这种 ...
- 多线程 | 03 | CAS机制
Compare and swap(CAS) 当前的处理器基本都支持CAS,只不过每个厂家所实现的算法并不一样罢了,每一个CAS操作过程都包含三个参数:一个内存地址V,一个期望的值A和一个新值B,操作的 ...
- Java多线程01(Thread类、线程创建、线程池)
Java多线程(Thread类.线程创建.线程池) 第一章 多线程 1.1 多线程介绍 1.1.1 基本概念 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于 ...
- 多线程的CAS
CAS Compare And Swap (Compare And Exchange) / 自旋 / 自旋锁 / 无锁 独占锁:独占锁是一种悲观锁,synchronized就是一种独占锁,会导致其它所 ...
- Java 多线程 01
多线程· Runnable 和 Thread 多线程的引入 * A:什么是线程 * 线程是程序执行的一条路径,一个进程中可以包含多条线程 * 多线程并发执行可以提高程序的效率,可以同时完成多项工作 * ...
- 多线程01.newThread的方式创建线程
1.java应用程序的main函数是一个线程,是被jvm启动的时候调用,线程的名字叫main 2.实现一个线程,必须创建一个thread实例,override run方法,并且调用start方法. 3 ...
- [Java复习] 多线程 Multithreading
Q1多线程基础 进程和线程? 进程: 1. 一段程序执行过程,动态的,相对而言程序是静态的.(与类和对象的关系类似) 2. CPU资源分配最小单元,包括CPU调度和资源管理. 3. 一个进程可以有多个 ...
- Synchronized锁性能优化偏向锁轻量级锁升级 多线程中篇(五)
不止一次的提到过,synchronized是Java内置的机制,是JVM层面的,而Lock则是接口,是JDK层面的 尽管最初synchronized的性能效率比较差,但是随着版本的升级,synchro ...
随机推荐
- 如何在交互式环境中执行Python程序
相信接触过Python的小伙伴们都知道运行Python脚本程序的方式有多种,目前主要的方式有:交互式环境运行.命令行窗口运行.开发工具上运行等,其中在不同的操作平台上还互不相同.今天,小编讲些Pyth ...
- 注解实现SpringCache自定义失效时间
注解实现SpringCache自定义失效时间 SpringCache是一个很方便的缓存框架,但是官方提供的缓存的配置只有全局的缓存失效时间,没有针对某个命名空间做配置,因为工作上业务的关系需要针对某一 ...
- Spring AOP学习笔记02:如何开启AOP
上文简要总结了一些AOP的基本概念,并在此基础上叙述了Spring AOP的基本原理,并且辅以一个简单例子帮助理解.从本文开始,我们要开始深入到源码层面来一探Spring AOP魔法的原理了. 要使用 ...
- Python 中的类的继承
class parent(object): def override1(self): print("Parent") class child(parent): def overri ...
- laravel表单中文错误提示本地化
<?php return [ /* |-------------------------------------------------------------------------- | V ...
- Github上可以涨薪30k的Java教程和实战项目终于可以免费下载了
写在前面 大家都知道 Github 是一个程序员福地,这里有各种厉害的开源框架.软件或者教程.这些东西对于我们学习和进步有着莫大的进步,所以我有了这个将 Github 上非常棒的 Java 开源项目整 ...
- 增值税发票税控开票软件助手Excel、ERP、SAP导入开票接口进行批量开票操作手册
写这遍文章的目的是方便以后个人使用,做个笔记记录. 首先我来说一下它是做什么用的,它的主要作用是把用户的开票数据,Excel数据.ERP 系统.SAP导入到增值税发票税控开票软件中,可用航信盘.百旺盘 ...
- python学习日记2019.9.2
1 定义一个字符串对象str str.title() #将字符串中用空格分隔的字符段首字母大写 str.rstrip() #将字符串末的空格删去 str.strip() #将字符串首末的空格删去 st ...
- async/await剖析
async/await剖析 JavaScript是单线程的,为了避免同步阻塞可能会带来的一些负面影响,引入了异步非阻塞机制,而对于异步执行的解决方案从最早的回调函数,到ES6的Promise对象以及G ...
- C++ vector迭代器访问二维数组
#include<iostream> #include<vector> int main(){ std::vector<int> arr(); // 创建一维数组 ...