JAVA并发API源码解析:原子类

在JAVA API的java.util.concurrent.atomic包下提供了一系列以基本类型包装类为基础的并发情况下不需要同步的类(借助硬件相关指令实现)。

首先看一个例子AutomicInteger:

public class AtomicInteger extends Number implements java.io.Serializable {
    private static final long serialVersionUID = 6214790243416807050L;
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;
    static {
      try {
        valueOffset = unsafe.objectFieldOffset
            (AtomicInteger.class.getDeclaredField("value"));
      } catch (Exception ex) { throw new Error(ex); }
    }
    private volatile int value;
    public AtomicInteger(int initialValue) {
        value = initialValue;
    }
    public AtomicInteger() {
    }
    public final int get() {
        return value;
    }
    public final void set(int newValue) {
        value = newValue;
    }
    public final void lazySet(int newValue) {
        unsafe.putOrderedInt(this, valueOffset, newValue);
    }
    public final int getAndSet(int newValue) {
        for (;;) {
            int current = get();
            if (compareAndSet(current, newValue))
                return current;
        }
    }
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }
    public final boolean weakCompareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }
    public final int getAndIncrement() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return current;
        }
    }
    public final int getAndDecrement() {
        for (;;) {
            int current = get();
            int next = current - 1;
            if (compareAndSet(current, next))
                return current;
        }
    }
    public final int getAndAdd(int delta) {
        for (;;) {
            int current = get();
            int next = current + delta;
            if (compareAndSet(current, next))
                return current;
        }
    }
    public final int incrementAndGet() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return next;
        }
    }
    public final int decrementAndGet() {
        for (;;) {
            int current = get();
            int next = current - 1;
            if (compareAndSet(current, next))
                return next;
        }
    }
    public final int addAndGet(int delta) {
        for (;;) {
            int current = get();
            int next = current + delta;
            if (compareAndSet(current, next))
                return next;
        }
    }
    public String toString() {
        return Integer.toString(get());
    }
    public int intValue() {
        return get();
    }
    public long longValue() {
        return (long)get();
    }
    public float floatValue() {
        return (float)get();
    }
    public double doubleValue() {
        return (double)get();
    }
}

源代码中没有volatile或者synchronized这些同步机制也没有锁,其实它的同步是通过硬件指令实现。Integer内部方法不是线程安全的所以并发编程推荐使用AtomicInteger类来替换包装类,但是原子类不是 java.lang.Integer 和相关类的通用替换方法,它们不定义诸如 hashCode 和 compareTo 之类的方法。例如:不提供AtomicDouble,开发人员需要使用 Double.doubleToLongBits 和 Double.longBitsToDouble
转换来保持 double 值。

此包还包含 Updater 类,该类可用于获取任意选定类的任意选定 volatile 字段上的 compareAndSet 操作。解决volatile字段非原子操作的安全问题。

时间: 2024-08-11 05:43:05

JAVA并发API源码解析:原子类的相关文章

JAVA并发API源码解析:并发数据结构、线程、线程池及其应用

首先介绍Callable这个接口,它仅包含一个方法call,它是类似于Runnable接口,是Future并发设计模式下实际的任务执行单元,它能返回一个对象.我们可以实现它的子类并使用Future对象来提交它.现在我们再来看看Futrue,futrue提供了get方法来返回计算结果,cancel来中断任务.Future还会进一步被封装成FutureTask等任务类,这些任务会被提交给ExecutorService,ExecutorService(ThreadPoolExecutor是它的子类)是

Java集合---LinkedList源码解析

一.源码解析1. LinkedList类定义2.LinkedList数据结构原理3.私有属性4.构造方法5.元素添加add()及原理6.删除数据remove()7.数据获取get()8.数据复制clone()与toArray()9.遍历数据:Iterator()二.ListItr 一.源码解析 1. LinkedList类定义. public class LinkedList<E> extends AbstractSequentialList<E> implements List&

Java 8 ThreadLocal 源码解析

Java 中的 ThreadLocal是线程内的局部变量, 它为每个线程保存变量的一个副本.ThreadLocal 对象可以在多个线程中共享, 但每个线程只能读写其中自己的副本. 目录: 代码示例 源码解析 InheritableThreadLocal ThreadLocalMap Get 流程 Set 流程 Remove 代码示例 我们编写一个简单的示例: import java.util.Random; import java.util.concurrent.ExecutorService;

Java之Object源码解析

Object类作为所有类层次的根源,有着非常重要的作用,每个类都让Object作为其超类,所有的对象包括数组,都实现了Object里面定义的方法,总之一句话,凡是有对象的地方就一定实现了Object类的方法 首先我们知道,Object类里有如下几种方法: Class<?> getClass();  //返回当前Object的运行类 int hashCode(); //返回该对象的哈希值 boolea equals(Object obj); // 比较其它对象是否与此对象相等 protected

Java并发编程高阶技术 高性能并发框架源码解析与实战

第1章 课程介绍(Java并发编程进阶课程)什么是Disruptor?它一个高性能的异步处理框架,号称"单线程每秒可处理600W个订单"的神器,本课程目标:彻底精通一个如此优秀的开源框架,面试秒杀面试官.本章会带领小伙伴们先了解课程大纲与重点,然后模拟千万,亿级数据进行压力测试.让大家感性认知到Disruptor的强大.... 第2章 并发编程框架核心讲解本章带大家学习并发编程框架的基本使用与API,并介绍其内部各种组件的原理和运行机制.从而为后面的深入学习打下坚实的基础.如果对Dis

java IO 包源码解析

本文参考连接:http://blog.csdn.net/class281/article/details/24849275                         http://zhhphappy.iteye.com/blog/1562427 一.IO包简要类图 Java I/O流部分分为两个模块,即Java1.0中就有的面向字节的流(Stream),以及Java1.1中大幅改动添加的面向字符的流(Reader & Writer).添加面向字符的流主要是为了支持国际化,旧的I/O流仅支持

JAVA常用集合源码解析系列-ArrayList源码解析(基于JDK8)

文章系作者原创,如有转载请注明出处,如有雷同,那就雷同吧~(who care!) 一.写在前面 这是源码分析计划的第一篇,博主准备把一些常用的集合源码过一遍,比如:ArrayList.HashMap及其对应的线程安全实现,此文章作为自己相关学习的一个小结,记录学习成果的同时,也希望对有缘的朋友提供些许帮助. 当然,能力所限,难免有纰漏,希望发现的朋友能够予以指出,不胜感激,以免误导了大家! 二.稳扎稳打过源码 首先,是源码内部的成员变量定义以及构造方法: 1 /** 2 * Default in

Java之HashMap源码解析1

讲解HashMap<K,V>时,我们先看看在API文档中是怎么介绍的: 基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和null 键.(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同.)此类不保证映射的顺序,特别是它不保证该顺序恒久不变. 此实现假定哈希函数将元素适当地分布在各桶之间,可为基本操作(get 和 put)提供稳定的性能.迭代collection 视图所需的时间与 HashMap 实例的"

第三十四节,目标检测之谷歌Object Detection API源码解析

我们在第三十二节,使用谷歌Object Detection API进行目标检测.训练新的模型(使用VOC 2012数据集)那一节我们介绍了如何使用谷歌Object Detection API进行目标检测,以及如何使用谷歌提供的目标检测模型训练自己的数据.在训练自己的数据集时,主要包括以下几步: 制作自己的数据集,注意这里数据集在进行标注时,需要按照一定的格式.然后调object_detection\dataset_tools下对应的脚本生成tfrecord文件.如下图,如果我们想调用create