CAS, AQS, locks and concurrency utilities

1. CAS principle

Chinese called comparative exchange --- the Compare And Swap

CAS (V, E, N)

V represents the value to be updated;

E represents the expected value;

N represents the new value.

Compare principle: When the values of V and E, N only then assigned to V; if V and E are not equal abandon the changes; re-read, try to modify again.

1.1 How to ensure atomicity

Atomicity assembly instructions based hardware, using CPU instructions to ensure atomicity;

 // Unsafe 后门类,用于直接操作内存中的数据
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;

/**
 * CAS实现
 */
public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

/**
 * 使用自旋的方式保证线程安全
 */
public final int getAndUpdate(IntUnaryOperator updateFunction) {
    int prev, next;
    do {
        prev = get();
        next = updateFunction.applyAsInt(prev);
    } while (!compareAndSet(prev, next));
    return prev;
}

The drawback 1.2 CAS

  • Cycle time is too long

    Some classes limit the number of spins

  • Atomic operation can only guarantee a shared variable

  • ABA problem

    If a value is A, it became a B, and then turned into A, then check the CAS will find the time did not change, but in essence it has changed, which is called the ABA problem.

    Use class AtomicStampedReference to solve the ABA problem.

    If the current reference is == to the expected value, and the current flag value == the expected value of the flag, the flag will be current references and the current value assigned to the updated value.

    /**
     * CAS实现
     *
     * @param expectedReference     引用的预期值
     * @param newReference          引用的新值
     * @param expectedStamp         标志的预期值
     * @param newStamp              标志的新值
     */
    public boolean compareAndSet(V   expectedReference,
                                 V   newReference,
                                 int expectedStamp,
                                 int newStamp) {
        Pair<V> current = pair;
        return
            expectedReference == current.reference &&
            expectedStamp == current.stamp &&
            ((newReference == current.reference &&
              newStamp == current.stamp) ||
             casPair(current, Pair.of(newReference, newStamp)));
    }

2. AQS principle

The acronym AQS ---- AbstractQueuedSynchronizer

Subclass defined as non-public internal helper class (private inner class inherits AQS); write lock when a helper, provides a template function is to acquire the lock and release the lock.

acquire (int arg) Acquires in exclusive mode, ignoring interrupts.

acquireShared (int arg) Acquires in shared mode, ignoring interrupts.

tryAcquire (arg) Attempts to acquire in exclusive mode state.

tryAcquireShared (int arg) Attempts to acquire in shared mode state

release (int arg) release in exclusive mode.

releaseShared (int arg) release in shared mode

3. Concurrent Tools

3.1 CountDownLatch (for flight)

3.2 CyclieBarries

3.3 Semaphore

Guess you like

Origin www.cnblogs.com/zhangqirong/p/11489398.html