大纲:

  1. cas
  2. atomic

一、cas

cas:compareAndSwap,一种乐观锁。

cas思想:cas需要三个值,v是内存值,e是期望值,n是要修改的值。当内存中的值v等于预期值e(说明内存中的值没有被其他线程修改)、才可以修改v为n。

cas伪代码

boolean cas(int v,int e,int n){
if(v==e){
v=n;
return true;
}else {
return false;
}
}

cas是unsafe类中的native方法,是原子操作,保证线程安全。

二、atomic

在java.util.concurrent.atomic包中,提供了许多拥有原子操作的类,供并发编程使用。这个包中的类大都使用了cas操作来保证操作的原子性。

以AtomicInteger为例,看下如何使用cas实现原子操作,这里为java1.8以下的源码:

public class AtomicInteger extends Number implements java.io.Serializable {

    private volatile int value; //volatile保证可见性,一个线程更新后,其他线程立即可见

    public final int get() {
return value;
} public AtomicInteger(int initialValue) {
value = initialValue;
} public final int getAndIncrement() {
for (;;) {
int current = get();//预期值e
int next = current + 1;//要修改的值n
if (compareAndSet(current, next))
return current;
}
//这个相当于线程安全的a++操作,其思想就是不断进行cas操作,直至成功
} public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
//给bootStrap类加载器用的unsafe中全部是native方法。
// valueOffset为变量在内存中偏移地址,用来找内存中的值v
} ......
}

ABA问题:一个线程在cas操作时,期望值是A,另一个线程修改了期望值为B,就会导致cas操作失败。但是如果这时候又有一个线程再次修改期望值为A,cas操作将成功。

如何解决:atomic包下AtomicStampedReference

public class AtomicStampedReference<V> {

    private static class Pair<T> {
final T reference;
final int stamp;
private Pair(T reference, int stamp) {
this.reference = reference;
this.stamp = stamp;
}
static <T> Pair<T> of(T reference, int stamp) {
return new Pair<T>(reference, stamp);
}
} private volatile Pair<V> pair; public AtomicStampedReference(V initialRef, int initialStamp) {
pair = Pair.of(initialRef, initialStamp);
//AtomicStampedReference内部有一个静态内部类pair,pair不仅封装了数据还封装了一个stamp用于区分每次修改
} public boolean compareAndSet(V expectedReference,
V newReference,
int expectedStamp,
int newStamp) {
Pair<V> current = pair;
return
expectedReference == current.reference &&
expectedStamp == current.stamp &&
((newReference == current.reference &&
newStamp == current.stamp) ||
casPair(current, Pair.of(newReference, newStamp))); //cas比较pair对象(不仅比较内存值如期望值,同时比较期望stamp与内存stamp)
} private boolean casPair(Pair<V> cmp, Pair<V> val) {
return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val);
} ...
}

java多线程-cas及atomic的更多相关文章

  1. Java 多线程 volitile 和 atomic

    Java 多线程 volitile 和 atomic volitile关键字 public class MTester { public static class TestKey{ int x = 0 ...

  2. Java多线程--CAS

    在Java多线程并发的情况下同时对一个变量进行操作会出现线程安全的问题,假如我们现在使用20个线程对一个变量不停累加1,代码如下: 1 public class ThreadDemo implemen ...

  3. Java多线程系列九——Atomic类

    参考资料:https://fangjian0423.github.io/2016/03/16/java-AtomicInteger-analysis/http://www.cnblogs.com/54 ...

  4. java多线程系列5 atomic简介

    先看一个例子,AtomicInteger 实现的线程安全的累加器 public class AtomicIntTest { public static void main(String[] args) ...

  5. java多线程系列 目录

    Java多线程系列1 线程创建以及状态切换    Java多线程系列2 线程常见方法介绍    Java多线程系列3 synchronized 关键词    Java多线程系列4 线程交互(wait和 ...

  6. java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析

    java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java ...

  7. Java多线程系列——原子类的实现(CAS算法)

    1.什么是CAS? CAS:Compare and Swap,即比较再交换. jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronou ...

  8. java 多线程12 : 无锁 实现CAS原子性操作----原子类

    由于java 多线程11:volatile关键字该文讲道可以使用不带锁的情况也就是无锁使变量变成可见,这里就理解下如何在无锁的情况对线程变量进行CAS原子性及可见性操作 我们知道,在并发的环境下,要实 ...

  9. Java并发(十二):CAS Unsafe Atomic

    一.Unsafe Java无法直接访问底层操作系统,而是通过本地(native)方法来访问.不过尽管如此,JVM还是开了一个后门,JDK中有一个类Unsafe,它提供了硬件级别的原子操作. 这个类尽管 ...

随机推荐

  1. spark介绍3

  2. JAVA并发设计模式学习笔记(二)—— Single Threaded Execution Pattern

    注:本文的主要参考资料为结城浩所著<JAVA多线程设计模式>. 单线程执行模式(Single Threaded Execution Pattern)是最简单的多线程设计模式,几乎所有其他的 ...

  3. 2.5 《硬啃设计模式》第7章 车手选车 - 生成器(Builder Pattern)

    某赛车游戏,玩家可以选择不同的车,这些车其实是采用不同性能的配件组成的,如:车胎.发动机等. 玩家选择一部车,其实就是new了一部车. 你如何考虑“new car”的代码? 要new这个车,可能需要先 ...

  4. jsp乱码的问题

    大家在JSP的开发过程中,经常出现中文乱码的问题,可能一至困扰着大家,现把JSP开发中遇到的中文乱码的问题及解决办法写出来供大家参考.首先了解一下Java中文问题的由来: Java的内核和class文 ...

  5. alpha七天冲刺计划

    alpha七天冲刺计划(更新ing) 第一天:https://www.cnblogs.com/renluqian/p/9895895.html 第二天: 第三天: 第四天: 第五天: 第六天: 第七天 ...

  6. nginx中级应用-续

    1.server下配置的每个location,都需要有自己的一套代理配置 即要么加入: root  某个目录 要么加入 proxy_pass 某个地址;  proxy_redirect off; # ...

  7. js 格式化时间

    //格式化时间 function time_format(time) { return new Date(parseInt(time) * 1000).toLocaleString().replace ...

  8. 自定义spring valid方式实现验证

    推荐:http://blog.csdn.net/xulianboblog/article/details/51694924

  9. Android 使用pk10系统架设RecyclerView实现轮播图

    一.需求 ViewPager有个天生的缺陷是View无法重用,此外pk10系统架设详情咨询[企娥166848365]ViewPager的滑动过程会频繁requestLayout,尽管可以通过addVi ...

  10. Dapper扩展Dapper.Common框架 Linq To Sql 底层源码.net ORM框架

    源代码:https://github.com/1448376744/Dapper.CommonNUGET: Dapper.CommonQQ群:642555086 一.基本结构,此处可用委托,或动态代理 ...