线程安全之原子操作 待续~

原子操作,可以是一个步骤,也可以是多个操作步骤,但是其顺序不可以被打乱,也不可以被切割而只执行其中一部分(不可中断性),将整个操作视为一个整体,资源在该次操作中保持一致,这是原子性的核心特征。

CAS机制

compare and swap,属于硬件同步原语,处理器提供了基本内存操作的原子性保证。

CAS操作,需要输入两个数值,一个旧值一个新值,在操作期间先比较下旧值有没有发生变化,如果没有发生变化,才交换成新值;如果发生了变化,则不交换。

使用Java中Unsafe类实现CAS机制:

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.TimeUnit;

public class UnsafeTest {

    private volatile int index = 0;

    // 类似直接操作内存
    private static Unsafe unsafe;

    // 属性内存偏移量
    private static long indexOffset;

    static {
        try {
            // 通过反射拿到对象
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            unsafe = (Unsafe) theUnsafe.get(null);
            // 通过属性偏移量,定位内存中具体对象内具体属性的内存地址
            indexOffset = unsafe.objectFieldOffset(UnsafeTest.class.getDeclaredField("index"));
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public void incr() {
        int currentIndex;
        int newIndex;
        do {
            currentIndex = unsafe.getIntVolatile(this, indexOffset);
            newIndex = currentIndex + 1;
        } while (!unsafe.compareAndSwapInt(this, indexOffset, currentIndex, newIndex));
        // CAS 如果index值发生变化,操作失败,直到修改成功跳出循环
    }

    public int getIndex() {
        return index;
    }

    public static void main(String[] args) throws InterruptedException {
        UnsafeTest unsafeTest = new UnsafeTest();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 10000; j++) {
                    unsafeTest.incr();
                }
            }).start();
        }
        TimeUnit.SECONDS.sleep(2);
        System.out.println(unsafeTest.getIndex());
    }

}

当然在JDK中已经给我们提供了很多原子操作封装类,在java.util.concurrent.atomic这个包下,也就是平常说的JUC包下的atomic包;

原子类分四类

  1. 基本类型
    1. AtomicBoolean
    2. AtomicInteger
    3. AtomicLong
  2. 数组类型
    1. AtomicIntegerArray
    2. AtomicLongArray
    3. AtomicReferenceArray
  3. 引用类型
    1. AtomicReference
    2. AtomicStampedReference
    3. AtomicMarkableReference
  4. 对象属性修改类型
    1. AtomicIntegerFieldUpdater
    2. AtomicLongFieldUpdater
    3. AtomicReferenceFieldUpdater

猜你喜欢

转载自blog.csdn.net/hellboy0621/article/details/106202128
今日推荐