`

AtomicInteger

阅读更多
AtomicInteger


一、总结

1.jdk 1.8.0

2.

  • 基于CAS的乐观锁实现
  • 基于JNI调用硬件级别的锁实现原子性操作
  • CAS算法,此算法是由unsafe的底层代码实现,它是一个原子的操作,CAS(V,E,N) V 变量,E expected  预期的旧值,N new 新值,Compare And Swap 比较交换,仅当 V中存放的值与E相等时,才将V赋值为N;否则,不做任何处理
  • 语言层面不做处理,我们将其交给硬件—CPU和内存,利用CPU的多处理能力,实现硬件层面的阻塞,再加上volatile变量的特性即可实现基于原子操作的线程安全。所以说,CAS并不是无阻塞,只是阻塞并非在语言、线程方面,而是在硬件层面,所以无疑这样的操作会更快更高效


二、源码分析

package java.util.concurrent.atomic;
import java.util.function.IntUnaryOperator;
import java.util.function.IntBinaryOperator;
import sun.misc.Unsafe;

/**
 * An {@code int} value that may be updated atomically.  See the
 * {@link java.util.concurrent.atomic} package specification for
 * description of the properties of atomic variables. An
 * {@code AtomicInteger} is used in applications such as atomically
 * incremented counters, and cannot be used as a replacement for an
 * {@link java.lang.Integer}. However, this class does extend
 * {@code Number} to allow uniform access by tools and utilities that
 * deal with numerically-based classes.
 *
 * @since 1.5
 * @author Doug Lea
*/
public class AtomicInteger extends Number implements java.io.Serializable {

    private static final long serialVersionUID = 6214790243416807050L;



  • Number,作用是Integer与其他数据类型之间的转换
  • Serializable,作用是序列化



    // setup to use Unsafe.compareAndSwapInt for updates
    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); }
    }



  • sun.misc.Unsafe的compareAndSwapInt方法获取类字段的偏移地址,进而通过对象的起始地址与偏移量地址可以读取字段的值


    private volatile int value;


  • value是一个volatile变量,在内存中可见,任何线程都不允许对其进行拷贝,因此JVM可以保证任何时刻任何线程总能拿到该变量的最新值。此处value的值,可以在AtomicInteger类初始化的时候传入,也可以留空,留空则自动赋值为0


    /**
     * Creates a new AtomicInteger with the given initial value.
     *
     * @param initialValue the initial value
     */
    public AtomicInteger(int initialValue) {
        value = initialValue;
    }

    /**
     * Creates a new AtomicInteger with initial value {@code 0}.
     */
    public AtomicInteger() {
    }

    /**
     * Gets the current value.
     *
     * @return the current value
     */
    public final int get() {
        return value;
    }

    /**
     * Sets to the given value.
     *
     * @param newValue the new value
     */
    public final void set(int newValue) {
        value = newValue;
    }

    /**
     * Eventually sets to the given value.
     *
     * @param newValue the new value
     * @since 1.6
     */
    public final void lazySet(int newValue) {
        unsafe.putOrderedInt(this, valueOffset, newValue);
    }

    /**
     * Atomically sets to the given value and returns the old value.
     *
     * @param newValue the new value
     * @return the previous value
     */
    public final int getAndSet(int newValue) {
        return unsafe.getAndSetInt(this, valueOffset, newValue);
    }

    /**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     *
     * @param expect the expected value
     * @param update the new value
     * @return {@code true} if successful. False return indicates that
     * the actual value was not equal to the expected value.
     */
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

    /**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     *
     * <p><a href="package-summary.html#weakCompareAndSet">May fail
     * spuriously and does not provide ordering guarantees</a>, so is
     * only rarely an appropriate alternative to {@code compareAndSet}.
     *
     * @param expect the expected value
     * @param update the new value
     * @return {@code true} if successful
     */
    public final boolean weakCompareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

    /**
     * Atomically increments by one the current value.
     *
     * @return the previous value
     */
    public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }

    /**
     * Atomically decrements by one the current value.
     *
     * @return the previous value
     */
    public final int getAndDecrement() {
        return unsafe.getAndAddInt(this, valueOffset, -1);
    }

    /**
     * Atomically adds the given value to the current value.
     *
     * @param delta the value to add
     * @return the previous value
     */
    public final int getAndAdd(int delta) {
        return unsafe.getAndAddInt(this, valueOffset, delta);
    }

    /**
     * Atomically increments by one the current value.
     *
     * @return the updated value
     */
    public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }

    /**
     * Atomically decrements by one the current value.
     *
     * @return the updated value
     */
    public final int decrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
    }

    /**
     * Atomically adds the given value to the current value.
     *
     * @param delta the value to add
     * @return the updated value
     */
    public final int addAndGet(int delta) {
        return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
    }

    /**
     * Atomically updates the current value with the results of
     * applying the given function, returning the previous value. The
     * function should be side-effect-free, since it may be re-applied
     * when attempted updates fail due to contention among threads.
     *
     * @param updateFunction a side-effect-free function
     * @return the previous value
     * @since 1.8
     */
    public final int getAndUpdate(IntUnaryOperator updateFunction) {
        int prev, next;
        do {
            prev = get();
            next = updateFunction.applyAsInt(prev);
        } while (!compareAndSet(prev, next));
        return prev;
    }

    /**
     * Atomically updates the current value with the results of
     * applying the given function, returning the updated value. The
     * function should be side-effect-free, since it may be re-applied
     * when attempted updates fail due to contention among threads.
     *
     * @param updateFunction a side-effect-free function
     * @return the updated value
     * @since 1.8
     */
    public final int updateAndGet(IntUnaryOperator updateFunction) {
        int prev, next;
        do {
            prev = get();
            next = updateFunction.applyAsInt(prev);
        } while (!compareAndSet(prev, next));
        return next;
    }

    /**
     * Atomically updates the current value with the results of
     * applying the given function to the current and given values,
     * returning the previous value. The function should be
     * side-effect-free, since it may be re-applied when attempted
     * updates fail due to contention among threads.  The function
     * is applied with the current value as its first argument,
     * and the given update as the second argument.
     *
     * @param x the update value
     * @param accumulatorFunction a side-effect-free function of two arguments
     * @return the previous value
     * @since 1.8
     */
    public final int getAndAccumulate(int x,
                                      IntBinaryOperator accumulatorFunction) {
        int prev, next;
        do {
            prev = get();
            next = accumulatorFunction.applyAsInt(prev, x);
        } while (!compareAndSet(prev, next));
        return prev;
    }

    /**
     * Atomically updates the current value with the results of
     * applying the given function to the current and given values,
     * returning the updated value. The function should be
     * side-effect-free, since it may be re-applied when attempted
     * updates fail due to contention among threads.  The function
     * is applied with the current value as its first argument,
     * and the given update as the second argument.
     *
     * @param x the update value
     * @param accumulatorFunction a side-effect-free function of two arguments
     * @return the updated value
     * @since 1.8
     */
    public final int accumulateAndGet(int x,
                                      IntBinaryOperator accumulatorFunction) {
        int prev, next;
        do {
            prev = get();
            next = accumulatorFunction.applyAsInt(prev, x);
        } while (!compareAndSet(prev, next));
        return next;
    }

    /**
     * Returns the String representation of the current value.
     * @return the String representation of the current value
     */
    public String toString() {
        return Integer.toString(get());
    }

    /**
     * Returns the value of this {@code AtomicInteger} as an {@code int}.
     */
    public int intValue() {
        return get();
    }

    /**
     * Returns the value of this {@code AtomicInteger} as a {@code long}
     * after a widening primitive conversion.
     * @jls 5.1.2 Widening Primitive Conversions
     */
    public long longValue() {
        return (long)get();
    }

    /**
     * Returns the value of this {@code AtomicInteger} as a {@code float}
     * after a widening primitive conversion.
     * @jls 5.1.2 Widening Primitive Conversions
     */
    public float floatValue() {
        return (float)get();
    }

    /**
     * Returns the value of this {@code AtomicInteger} as a {@code double}
     * after a widening primitive conversion.
     * @jls 5.1.2 Widening Primitive Conversions
     */
    public double doubleValue() {
        return (double)get();
    }

}



博文参考:
AtomicInteger源码分析
分享到:
评论

相关推荐

    AtomicInteger 浅谈

    《AtomicInteger 浅谈》 在Java编程中,原子性操作是并发编程中非常关键的一环,它确保了在多线程环境下数据的正确性和一致性。AtomicInteger是Java并发包java.util.concurrent.atomic中的一个类,提供了对单个整型...

    Java中的原子操作:深入探索AtomicInteger的实现与应用

    在Java的并发编程中,AtomicInteger 是一个非常重要的原子类,它提供了一种无锁的机制来保证整数操作的原子性。本文将详细介绍 AtomicInteger 的工作原理、使用方法以及如何在实际项目中应用它。 AtomicInteger 是...

    AtomicInteger并发测试

    测试java.util.concurrent.atomic.AtomicInteger的类 与直接使用int做区别

    ViewPager+AtomicInteger实现广告轮播

    本项目通过结合ViewPager和AtomicInteger实现了一个高效的广告轮播功能,具有自动轮播和响应用户触摸事件的能力。 首先,`ViewPager`是Android SDK提供的一种强大的组件,主要用于展示可滑动的页面集合。在这个案例...

    Java中对AtomicInteger和int值在多线程下递增操作的测试

    为了确保数据在并发访问时的正确性,Java提供了一系列的原子类,包括`AtomicInteger`,它为整数类型的变量提供了线程安全的更新操作。这个话题将深入探讨`AtomicInteger`与普通`int`变量在多线程环境下进行递增操作...

    Java AtomicInteger类使用方法实例讲解

    Java AtomicInteger类使用方法实例讲解 Java AtomicInteger类是Java语言中的一种高效的原子操作类,主要用于在高并发环境下的高效程序处理。AtomicInteger类提供了一种线程安全的加减操作接口,能够帮助开发者简化...

    Java AtomicInteger类的使用方法详解

    Java AtomicInteger类的使用方法详解 Java AtomicInteger类是Java中提供的一种原子操作的Integer类,通过线程安全的方式操作加减。它可以在高并发情况下使用,提供原子操作来进行Integer的使用。 Atomicinteger类...

    java并发之AtomicInteger源码分析

    Java并发之AtomicInteger源码分析 AtomicInteger是Java并发包下面提供的原子类,主要操作的是int类型的整型,通过调用底层Unsafe的CAS等方法实现原子操作。下面是对AtomicInteger的源码分析。 1. 什么是原子操作...

    AtomicInteger的使用,CAS的工作原理

    AtomicInteger atomicInteger = new AtomicInteger(5); atomicInteger.compareAndSet(5, 2020) + \t current data is + atomicInteger.get()) /** * Atomically sets the value to the given updated value * if ...

    AtomicIntegerExample:AtomicInteger示例

    AtomicInteger示例AtomicInteger用于原子增量计数器之类的应用程序。 简短的示例代码: public class AtomicIntegerExample { private final ExecutorService execService = Executors . newFixedThreadPool( 100 );...

    使用Java的Memory Model实现一个简单的计数器.txt

    通过使用`AtomicInteger`实现的简单计数器示例,我们可以看到,在多线程环境下,利用`AtomicInteger`能够有效地保证数据操作的原子性和线程安全性。这对于开发高性能、高并发的应用程序来说是非常重要的。此外,通过...

    15个顶级Java多线程面试题及回答.docx

    private AtomicInteger count = new AtomicInteger(0); public void increment() { count.incrementAndGet(); } public int getCount() { return count.get(); } } ``` #### 题目八:`volatile`关键字 **...

    java多线程自增效率比较及原理解析

    AtomicInteger count = new AtomicInteger(); count.addAndGet(1); ``` **效率分析**: `AtomicInteger`相比`synchronized`具有更好的并发性能,尤其是在高并发场景下。 ##### 3. LongAdder `LongAdder`是JDK8引入的...

    Java 投票(自动加一)

    private AtomicInteger voteCount = new AtomicInteger(0); public void vote() { voteCount.incrementAndGet(); } public int getVoteCount() { return voteCount.get(); } } ``` 在这个例子中,`vote()`...

    Java并发——无锁实现

    AtomicInteger atomicInteger = new AtomicInteger(0); // 获取当前值 int current = atomicInteger.get(); // 设置新值 atomicInteger.set(10); // 增加1并返回旧值 int previous = atomicInteger....

    springboot 集成 webSocket

    private static AtomicInteger online = new AtomicInteger(); //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。 private static ConcurrentHashMap, Session&gt; sessionPools = new ...

    java多线程中的原子操作

    在Java中,`java.util.concurrent.atomic`包提供了多种原子类,如AtomicInteger、AtomicLong等,这些类支持原子性的增加、减小、更新等操作,避免了显式的同步锁的使用,提高了并发性能。例如,AtomicInteger的...

    15 原子性轻量级实现—深入理解Atomic与CAS.pdf

    `Atomic`类位于`java.util.concurrent.atomic`包中,包括如`AtomicInteger`、`AtomicLong`、`AtomicBoolean`等,分别对应不同类型的原子变量。它们提供了线程安全的更新操作,例如`incrementAndGet()`方法,能够在多...

    Java多线程编程的多线程编程中的挑战.docx

    private static final AtomicInteger COUNT_VALUE = new AtomicInteger(0); int count() { while (COUNT_VALUE.get() &gt;= 100) { COUNT_VALUE.set(1); } COUNT_VALUE.incrementAndGet(); return COUNT_VALUE....

Global site tag (gtag.js) - Google Analytics