线程安全之原子性问题

原子性问题说明:

  1. i++ 的原子性问题:i++ 的操作实际上分为三个步骤“读–改--写”

       int i = 10;
       i = i++; //10
    
       int temp = i;
       i = i + 1;
       i = temp;
    
  2. 原子变量:在 java.util.concurrent.atomic 包下提供了一些原子变量。

  • AtomicBoolean
    AtomicInteger
    AtomicIntegerArray
    AtomicIntegerFieldUpdater
    AtomicLong
    AtomicLongArray
    AtomicLongFieldUpdater
    AtomicMarkableReference
    AtomicReference
    AtomicReferenceArray
    AtomicReferenceFieldUpdater
    AtomicStampedReference
  1. 保证原子性方式:
    1. volatile 保证内存可见性
    2. CAS(Compare-And-Swap) 算法保证数据变量的原子性
    CAS 算法是硬件对于并发操作的支持
    CAS 包含了三个操作数:
    ①内存值 V
    ②预估值 A
    ③更新值 B
    当且仅当 V == A 时, V = B; 否则,不会执行任何操作。(注意区分判断和赋值)
  • CAS算法屏弃了synchronize处理多线程中没有获得锁导致线程放弃执行权的方法,因此高效。
/*
 * 模拟 CAS 算法
 */
class TestCompareAndSwap {
    public static void main(String[] args) {
        final CompareAndSwap cas = new CompareAndSwap();
        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    int expectedValue = cas.get();
                    boolean b = cas.compareAndSet(expectedValue, (int) (Math.random() * 101));
                    System.out.println(b);
                }
            }).start();
        }
    }
}

class CompareAndSwap {
    private int value;
    //获取内存值
    public synchronized int get() {
        return value;
    }
    //比较
    public synchronized int compareAndSwap(int expectedValue, int newValue) {
        int oldValue = value;

        if (oldValue == expectedValue) {
            this.value = newValue;
        }

        return oldValue;
    }

    //设置
    public synchronized boolean compareAndSet(int expectedValue, int newValue) {
        return expectedValue == compareAndSwap(expectedValue, newValue);
    }
}

发布了51 篇原创文章 · 获赞 20 · 访问量 1547

猜你喜欢

转载自blog.csdn.net/qq_39711439/article/details/101418650
今日推荐