原子更新基本类型

原子更新数组

原子更新抽象类型

原子更新字段

原子更新基本类型:

  1. package com.roocon.thread.t8;
  2.  
  3. import java.util.concurrent.atomic.AtomicInteger;
    import java.util.concurrent.atomic.AtomicIntegerArray;
  4.  
  5. public class Sequence {
    private AtomicInteger value = new AtomicInteger(0);
    private int [] s = {2,1,4,6};
    AtomicIntegerArray a = new AtomicIntegerArray(s);
  6.  
  7. public int getNext(){
    a.getAndIncrement(2);//给下标为2的元素加1
    a.getAndAdd(2, 10);//获取下标为2的元素,并且加10
    for (int i=0; i < a.length(); i++){
    System.out.println(a.get(i));
    }
    return value.getAndIncrement();
    }
  8.  
  9. public static void main(String[] args) {
    Sequence sequence = new Sequence();
    new Thread(new Runnable() {
    @Override
    public void run() {
    while (true){
    System.out.println(Thread.currentThread().getName()+" "+sequence.getNext());
    try {
    Thread.sleep(100);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }).start();
    new Thread(new Runnable() {
    @Override
    public void run() {
    while (true){
    System.out.println(Thread.currentThread().getName()+" "+sequence.getNext());
    try {
    Thread.sleep(100);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }).start();
    new Thread(new Runnable() {
    @Override
    public void run() {
    while (true){
    System.out.println(Thread.currentThread().getName()+" "+sequence.getNext());
    try {
    Thread.sleep(100);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }).start();
    }
    }

运行结果:

  1. Thread-0 0
  2. Thread-1 1
  3. Thread-2 2
  4. Thread-0 3
  5. Thread-1 4
  6. Thread-2 5
  7. ...
  1. package com.roocon.thread.t8;
  2.  
  3. import java.util.concurrent.atomic.AtomicInteger;
  4. import java.util.concurrent.atomic.AtomicIntegerArray;
  5. import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
  6. import java.util.concurrent.atomic.AtomicReference;
  7.  
  8. public class Sequence {
  9. private AtomicInteger value = new AtomicInteger(0);
  10. AtomicReference<User> user = new AtomicReference<>(); //对user的set和get执行原子操作
  11. AtomicIntegerFieldUpdater<User> old = AtomicIntegerFieldUpdater.newUpdater(User.class, "old");
  12.  
  13. public int getNext(){
  14. User user = new User();
  15. System.out.println(old.getAndIncrement(user));
  16. System.out.println(old.getAndIncrement(user));
  17. System.out.println(old.getAndIncrement(user));
  18. return value.getAndIncrement();
  19. }
  20.  
  21. public static void main(String[] args) {
  22. Sequence sequence = new Sequence();
  23. new Thread(new Runnable() {
  24. @Override
  25. public void run() {
  26. System.out.println(Thread.currentThread().getName()+" "+sequence.getNext());
  27. try {
  28. Thread.sleep(100);
  29. } catch (InterruptedException e) {
  30. e.printStackTrace();
  31. }
  32. }
  33. }).start();
  34. }
  35. }

运行结果:

  1. 0
  2. 1
  3. 2
  4. Thread-0 0

对CAS的源码理解:--初步理解

在AtomicInteger中有这样一段源码:

  1. public final int getAndUpdate(IntUnaryOperator updateFunction) {
  2. int prev, next;
  3. do {
  4. prev = get();
  5. next = updateFunction.applyAsInt(prev);
  6. } while (!compareAndSet(prev, next));
  7. return prev;
  8. }
  1. public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }
  1.  

其中,compareAndSwap就是CAS的缩写。如果prev和next不相等,则返回true。否则,返回false。最终是通过unsafe来实现的。

以上代码表示,如果compareAndSet返回true,则while条件为false,退出循环,返回prev值。如果compareAndSet返回false,则while为true,继续执行循环体,重新获取prev的值,重新获取更新值,直到返回的compareAndSet值为true。

演示源码大致步骤如下:

  1. Object prev = get(); //
  2. next = prev + 1;
  3. boolean flag = cas(prev, next);
  4. if (flag) {
  5. return prev;
  6. }else {
  7. go to 1
  8. }

JDK提供的原子类原理与使用的更多相关文章

  1. Java并发编程原理与实战十三:JDK提供的原子类原理与使用

    原子更新基本类型 原子更新数组 原子更新抽象类型 原子更新字段 原子更新基本类型:   package com.roocon.thread.t8; import java.util.concurren ...

  2. JDK提供的原子类和AbstractQueuedSynchronizer(AQS)

    大致分成: 1.原子更新基本类型 2.原子更新数组 3.原子更新抽象类型 4.原子更新字段 import java.util.concurrent.atomic.AtomicInteger; impo ...

  3. 并发编程学习笔记(4)----jdk5中提供的原子类及Lock使用及原理

    (1)jdk中原子类的使用: jdk5中提供了很多原子类,它会使变量的操作变成原子性的. 原子性:原子性指的是一个操作是不可中断的,即使是在多个线程一起操作的情况下,一个操作一旦开始,就不会被其他线程 ...

  4. css 框架——base.css,作用是重设浏览器默认样式和提供通用原子类。自己留存

    今天发下我自己的 css 框架——base.css,作用是重设浏览器默认样式和提供通用原子类. @charset "utf-8"; /*! * @名称:base.css * @功能 ...

  5. B8 Concurrent JDK中的乐观锁与原子类

    [概述] 乐观锁采用的是一种无锁的思想,总是假设最好的情况,认为一个事务在读取数据的时候,不会有别的事务对数据进行修改,只需要在修改数据的时候判断原数据数据是否已经被修改了.JDK 中 java.ut ...

  6. 【漫画】CAS原理分析!无锁原子类也能解决并发问题!

    本文来源于微信公众号[胖滚猪学编程].转载请注明出处 在漫画并发编程系统博文中,我们讲了N篇关于锁的知识,确实,锁是解决并发问题的万能钥匙,可是并发问题只有锁能解决吗?今天要出场一个大BOSS:CAS ...

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

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

  8. 【Java并发工具类】原子类

    前言 为保证计数器中count=+1的原子性,我们在前面使用的都是synchronized互斥锁方案,加锁独占访问的方式未免太过霸道,于是我们来介绍另一种解决原子性问题的无锁方案:原子变量.在正式介绍 ...

  9. JUC包-原子类(AtomicInteger为例)

    目录 JUC包-原子类 为什么需要JUC包中的原子类 原子类原理(AtomicInteger为例) volatile CAS CAS的缺点 ABA问题 什么是ABA问题 ABA问题的解决办法 JUC包 ...

随机推荐

  1. php后台实现页面跳转的方法-转载

    地址:http://blog.csdn.net/abandonship/article/details/6459104 其中方法三的js代码在tp框架使用存在故障,一个是需要把代码写在一起(可能也不需 ...

  2. 学而不思则罔 - SAP云平台ABAP编程环境的由来和适用场景

    最近Jerry写了一系列关于SAP云平台ABAP编程环境的技术文章,这些文章都是围绕着在云上的ABAP编程环境的具体知识点来分享,比如要完成一个具体的开发需求,所需要的编程步骤.这些文章陆续收到一些读 ...

  3. java设计模式--观察者模式和事件监听器模式

    观察者模式 观察者模式又称为订阅—发布模式,在此模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知.这通常透过呼叫各观察者所提供的方法来实现.此种模式通常被用来事件 ...

  4. unity获取ugui上鼠标位置

    public class GetMousePos : MonoBehaviour { public Canvas canvas;//画布 private RectTransform rectTrans ...

  5. Android笔记(六十七) 自定义控件

    实际编程中,系统提供的控件往往无法满足我们的需求,一来是样子丑陋,二来是一些复杂的组合需要多次使用的话,每次都写一堆控件的组合会很耗费时间,所以我们将这些组件的组合自定义为一个新的控件,以后使用的时候 ...

  6. APC (Asynchronous Procedure Call)

    系统创建新线程时,会同时创建与这个线程相关联的队列,即异步过程调用(APC)的队列. 一些异步操作可以通过加入APC来实现,比如我现在学习的IO请求/完成. BOOL ReadFileEx( HAND ...

  7. git---怎样将分支上的一个单文件合并到主分支上(master)

    一.首先切换到主分支  注意将分支上的数据全部提交 以免造成数据冲突或丢失 git checkeout master 二.选择要合并的文件 git checkout --patch 分支名称  要合并 ...

  8. visual studio故障修复

    如果没有安装程序,直接在控制面板——>程序和功能,在列表中找到您安装的vs,右键选择更改,然后程序会启动,做一些准备.然后又三个选项,可以选择修复.

  9. Kotlin扩展作用域分析与扩展的根本作用解析

    在上一次https://www.cnblogs.com/webor2006/p/11219358.html学习了Kotlin的扩展,继续这个话题继续拓展,首先提出这么一个问题:假如我们扩展的方法跟类中 ...

  10. python实现Bencode解码方法

    近期搞项目中遇到Bencode解码的问题,就用Py写了个Bencode解码的代码.作为笔记保存参考. BEncoding是BitTorrent用在传输数据结构的编码方式,这种编码方式支持四种类型的数据 ...