原子变量与CAS算法小结
CAS算法
CAS(compare-and-swap)是一种硬件对并发的支持,针对多处理器操作而设计的处理器中的一种特殊指令,用于管理对共享数据的并发访问。
CAS是一种无锁非阻塞算法的实现。
CAS 包含了 3 个操作数:
需要读写的内存值V
进行比较的值A
拟写入的新值B当且仅当V的值等于A时,CAS通过原子方式用新值更新V的值,否则不会执行任何操作。
CAS操作过程如下所示
CAS算法模拟
/**
* 模拟CAS算法
*
* Created by 吴海飞 on 2017-1-22.
*/
public class TestCompareAndSwap {
public static void main(String[] args){
final CompareAndSwap cas = new CompareAndSwap();
for (int i = 0; i < 10; i++ ){
new Thread(new Runnable() {
@Override
public void run() {
int expectValue = cas.getValue();
boolean b = cas.compareAndSet(expectValue, (int)(Math.random() * 101));
System.out.println(b);
}
}
).start();
}
}
}
class CompareAndSwap{
private int value;
//获取内存值
public synchronized int getValue(){
return this.value;
}
//比较
public synchronized int compareAndSwap(int expectValue,int newValue){
int oldValue = this.value;
if(oldValue == expectValue){//如果期望值等于旧值
this.value = newValue;
}
return oldValue;
}
public synchronized boolean compareAndSet(int expectValue,int newValue){
return expectValue == compareAndSwap(expectValue, newValue);
}
}
原子变量
类的小工具包,支持在单个变量上解除锁的线程安全编程。事实上,此包中的类可将 volatile 值、字段和数组元素的概念扩展到那些也提供原子条件更新操作的类。
类 AtomicBoolean、 AtomicInteger、 AtomicLong 和 AtomicReference 的实例各自提供对相应类型单个变量的访问和更新。每个类也为该类型提供适当的实用工具方法。
AtomicIntegerArray、 AtomicLongArray 和 AtomicReferenceArray 类进一步扩展了原子操作,对这些类型的数组提供了支持。这些类在为其数组元素提供 volatile 访问语义方面也引人注目,这对于普通数组来说是不受支持的。
核心方法: boolean compareAndSet(expectedValue, updateValue)
java.util.concurrent.atomic 包下提供了一些原子操作的常用类:
- AtomicBoolean 、 AtomicInteger 、 AtomicLong 、AtomicReference
- AtomicIntegerArray 、 AtomicLongArray
- AtomicMarkableReference
- AtomicReferenceArray
- AtomicStampedReference
原子变量使用Demo
import java.util.concurrent.atomic.AtomicInteger;
/**
*一、i++ 的原子性问题:i++ 的操作实际上分为三个步骤“读-改-写”
* int i = 10;
* i = i++; //10
*
* int temp = i;
* i = i + 1;
* i = temp;
* 二、原子变量:在 java.util.concurrent.atomic 包下提供了一些原子变量。
* 1. volatile 保证内存可见性
* 2. CAS(Compare-And-Swap) 算法保证数据变量的原子性
* CAS 算法是硬件对于并发操作的支持
* CAS 包含了三个操作数:
* ①内存值 V
* ②预估值 A
* ③更新值 B
* 当且仅当 V == A 时, V = B; 否则,不会执行任何操作。
*/
public class AtomicDemo {
public static void main(String[] args) {
AtomicData ad = new AtomicData();
for (int i = 0; i < 10; i++) {
new Thread(ad).start();
}
}
}
class AtomicData implements Runnable{
//初始化原子变量
private AtomicInteger atomicData = new AtomicInteger(0);
@Override
public void run() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getAtomicData());
}
public int getAtomicData(){
return atomicData.getAndIncrement();//相当于atomicData++
}
}
原子变量与CAS算法小结的更多相关文章
- 三、原子变量与CAS算法
原子变量:jdk1.5 后 java.util.concurrent.atomic 包下提供了常用的原子变量: - AtomicBoolean - AtomicInteger - AtomicLong ...
- Java多线程-----原子变量和CAS算法
原子变量 原子变量保证了该变量的所有操作都是原子的,不会因为多线程的同时访问而导致脏数据的读取问题 Java给我们提供了以下几种原子类型: AtomicInteger和Ato ...
- 原子变量与CAS算法
原子变量 为了引出原子变量这个概念,我们先看一个例子. package com.ccfdod.juc; public class TestAtomicDemo { public static void ...
- volatile关键字与内存可见性&原子变量与CAS算法
1 .volatile 关键字:当多个线程进行操作共享数据时, 可以保证内存中的数据可见 2 .原子变量:jdk1.5后java.util.concurrent.atomic 包下提供常用的原子变量 ...
- 原子变量与CAS算法(二)
一.锁机制存在的问题 (1)在多线程竞争下,加锁.释放锁会导致比较多的上下文切换和调度延时,引起性能问题. (2)一个线程持有锁会导致其它所有需要此锁的线程挂起. (3)如果一个优先级高的线程等待一个 ...
- 计算机程序的思维逻辑 (70) - 原子变量和CAS
从本节开始,我们探讨Java并发工具包java.util.concurrent中的内容,本节先介绍最基本的原子变量及其背后的原理和思维. 原子变量 什么是原子变量?为什么需要它们呢? 在理解synch ...
- Java编程的逻辑 (70) - 原子变量和CAS
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...
- Java-JUC(三):原子性变量与CAS算法
原子性 并发程序正确地执行,必须要保证原子性.可见性以及有序性.只要有一个没有被保证,就有可能会导致程序运行不正确. 原子性:一个操作或多个操作要么全部执行完成且执行过程不被中断,要么就不执行. 可见 ...
- juc-2-原子变量与CAS算法
i++的原子性问题 例子 int i=10; i++; 结果 i=10 分析过程 在计算机 底层 会有生成一个临时变量 tem ...
随机推荐
- PHP怎么把经过UTF-8编码的中文字符转换成正常的中文
问题的场景: html 为utf-8编码<meta http-equiv="Content-Type" content="text/html; charset=UT ...
- ARM模式下创建Express Route
在Azure的ARM模式下,创建Express Route的命令和ASM模式下是有一些区别的. 本文将介绍在ARM模式下,如果创建Express Route的Circuit. 1. 查看支持的Serv ...
- 蓝桥杯 算法训练 ALGO-124 数字三角形
算法训练 数字三角形 时间限制:1.0s 内存限制:256.0MB 问题描述 (图3.1-1)示出了一个数字三角形. 请编一个程序计算从顶至底的某处的一条路 径,使该路径所经过的数字的总和 ...
- 用Unreal Engine绘制实时CG影像
转自:http://www.unrealchina.net/portal.php?mod=view&aid=225 近年来,对实时CG的关心热度越来越高,但要想弥补与预渲染方式的差异并不是那么 ...
- PHP类(三)-类的封装
设置私有成员 使用private关键字来设置私有成员,完成对成员的封装,封装后的成员在对象的外部不能被访问,如果访问会出现错误,在对象的内部能访问被封装的成员属性和方法. <?php class ...
- NodeJS之Url的使用
一.通过http模块中的request事件可以得到在服务端拿到客户端的有关url的数据(req.url),其中req.url得到的数据是端口号后的所有路径,之后通过调入url模块对获取到的req.ur ...
- linux 权限 homework
作业一: 1) 新建用户natasha,uid为1000,gid为555,备注信息为“master” useradd natasha -u 1000 -g 555 -c "master&qu ...
- MySQL学习笔记之一---字符编码和字符集
前言: 一般来说,出现中文乱码,都是客户端和服务端字符集不匹配导致的原因. (默认未指定字符集创建的数据库表,都是latinl字符集, 强烈建议使用utf8字符集) 保证不出现乱码的思想:保证客户 ...
- Shell编程进阶 1.2 shell结构及执行
创建一个shell脚本 mkdir shell vim first.sh #!/bin/bash ##The first test shell script. ##Written by wangsha ...
- 部署和调优 3.1 dns安装配置-1
安装配置DNS服务器 装一个bind,首先搜一下. yum list |grep bind bind.x86_64 我们安装这个 安装 yum install bind.x86_64 -y 看一下 ...