java并发编程 Atomic、CAS和AQS的介绍

Java并发编程进阶:深度剖析Atomic、CAS与AQS实现原理

引言:现代并发编程的基石

在多核处理器时代,高效并发控制是提升系统性能的关键。Java并发包(JUC)中的三大核心技术——Atomic原子类、CAS机制和AQS框架,构成了现代并发编程的基础设施。本文将通过原理剖析、源码解读和实战案例,带你深入理解这些核心技术的实现机制。

一、核心概念全景解析

1.1 Atomic原子类体系

实现原理

Atomic类实现
CAS原子操作
Unsafe类
volatile变量
内存屏障

类继承体系

  • 基础类型:AtomicInteger/AtomicLong/AtomicBoolean
  • 引用类型:AtomicReference/AtomicStampedReference
  • 数组类型:AtomicIntegerArray/AtomicLongArray
  • 字段更新:AtomicIntegerFieldUpdater

内存可见性保障

// AtomicInteger源码片段
public class AtomicInteger extends Number {
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private volatile int value; // volatile保证可见性
    
    public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }
}

1.2 CAS机制深度探秘

CPU指令级实现

  • x86架构:CMPXCHG指令
  • ARM架构:LL/SC指令对

ABA问题解决方案

// 使用AtomicStampedReference解决ABA问题
AtomicStampedReference<String> ref = new AtomicStampedReference<>("A", 0);

int[] stampHolder = new int[1];
String current = ref.get(stampHolder);
ref.compareAndSet(current, "B", stampHolder[0], stampHolder[0]+1);

CAS性能优化策略

  1. 自适应自旋(JVM实现)
  2. 批量操作(LongAdder的分段统计)
  3. 退避策略(指数退避算法)

1.3 AQS框架设计

CLH队列实现

CLH队列
Thread1 Node
Head
Thread2 Node
Thread3 Node
Tail

状态管理机制

  • 同步状态(state):volatile int类型
  • 节点状态(waitStatus):
    • CANCELLED(1)
    • SIGNAL(-1)
    • CONDITION(-2)
    • PROPAGATE(-3)

二、关键技术实现剖析

2.1 Atomic原子类高效实现

缓存行优化

// LongAdder的Cell类使用@Contended避免伪共享
@sun.misc.Contended 
static final class Cell {
    volatile long value;
    // ...
}

分段计数原理

LongAdder
竞争时
竞争时
竞争时
Cell1
Base值
Cell2
Cell3

2.2 AQS实现可重入锁

ReentrantLock类结构

public class ReentrantLock implements Lock {
    private final Sync sync; // 继承自AQS
    
    abstract static class Sync extends AbstractQueuedSynchronizer {
        // 实现tryAcquire等模板方法
    }
}

获取锁流程

Thread AQS CLH_Queue acquire(1) tryAcquire(1) 返回 addWaiter(Node.EXCLUSIVE) 返回节点 acquireQueued(node, arg) alt [获取成功] [获取失败] Thread AQS CLH_Queue

三、实战开发案例集

3.1 CAS 实战代码

ABA 问题解决方案
使用版本号(AtomicStampedReference)
import java.util.concurrent.atomic.AtomicStampedReference;

public class ABASolutionWithStamp {
    public static void main(String[] args) {
        // 使用 AtomicStampedReference 解决 ABA 问题
        AtomicStampedReference<String> ref = new AtomicStampedReference<>("A", 0);

        int[] stampHolder = new int[1];
        String current = ref.get(stampHolder);

        // 模拟 ABA 操作
        ref.compareAndSet(current, "B", stampHolder[0], stampHolder[0] + 1);
        ref.compareAndSet("B", "A", stampHolder[0] + 1, stampHolder[0] + 2);

        // 再次尝试更新
        if (ref.compareAndSet(current, "C", stampHolder[0], stampHolder[0] + 1)) {
            System.out.println("更新成功");
        } else {
            System.out.println("更新失败,可能发生了 ABA 问题");
        }
    }
}
使用 AtomicMarkableReference
import java.util.concurrent.atomic.AtomicMarkableReference;

public class ABASolutionWithMark {
    public static void main(String[] args) {
        // 使用 AtomicMarkableReference 解决 ABA 问题
        AtomicMarkableReference<String> ref = new AtomicMarkableReference<>("A", false);

        boolean[] markHolder = new boolean[1];
        String current = ref.get(markHolder);

        // 模拟 ABA 操作
        ref.compareAndSet(current, "B", markHolder[0], !markHolder[0]);
        ref.compareAndSet("B", "A", !markHolder[0], markHolder[0]);

        // 再次尝试更新
        if (ref.compareAndSet(current, "C", markHolder[0], !markHolder[0])) {
            System.out.println("更新成功");
        } else {
            System.out.println("更新失败,可能发生了 ABA 问题");
        }
    }
}
CAS 性能优化策略
自适应自旋(JVM 实现)

JVM 会根据当前系统的状态自动调整自旋的次数,避免长时间的自旋消耗过多的 CPU 资源。以下是一个简单的示例,模拟自适应自旋的效果:

import java.util.concurrent.atomic.AtomicInteger;

public class AdaptiveSpinExample {
    private static AtomicInteger counter = new AtomicInteger(0);

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            while (true) {
                int expect = counter.get();
                if (counter.compareAndSet(expect, expect + 1)) {
                    System.out.println("线程 1 更新成功,当前值: " + counter.get());
                    break;
                }
                // 模拟自适应自旋,可根据实际情况调整自旋次数
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread t2 = new Thread(() -> {
            while (true) {
                int expect = counter.get();
                if (counter.compareAndSet(expect, expect + 1)) {
                    System.out.println("线程 2 更新成功,当前值: " + counter.get());
                    break;
                }
                // 模拟自适应自旋,可根据实际情况调整自旋次数
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
批量操作(LongAdder 的分段统计)
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.LongAdder;

public class LongAdderExample {
    public static void main(String[] args) throws InterruptedException {
        LongAdder adder = new LongAdder();
        ExecutorService executor = Executors.newFixedThreadPool(10);

        // 模拟多线程并发增加操作
        for (int i = 0; i < 1000; i++) {
            executor.submit(() -> {
                adder.increment();
            });
        }

        executor.shutdown();
        while (!executor.isTerminated()) {
            // 等待所有任务完成
        }

        System.out.println("最终结果: " + adder.sum());
    }
}
退避策略(指数退避算法)
import java.util.concurrent.ThreadLocalRandom;

class Backoff {
    final int minDelay, maxDelay;
    int limit;

    public Backoff(int minDelay, int maxDelay) {
        this.minDelay = minDelay;
        this.maxDelay = maxDelay;
        this.limit = minDelay;
    }

    public void backoff() throws InterruptedException {
        int delay = ThreadLocalRandom.current().nextInt(limit);
        limit = Math.min(maxDelay, limit * 2);
        Thread.sleep(delay);
    }
}

public class BackoffExample {
    private static final int MIN_DELAY = 1;
    private static final int MAX_DELAY = 100;
    private static final int ATTEMPTS = 10;

    public static void main(String[] args) {
        Backoff backoff = new Backoff(MIN_DELAY, MAX_DELAY);

        for (int i = 0; i < ATTEMPTS; i++) {
            try {
                // 模拟 CAS 操作失败
                if (!simulateCAS()) {
                    System.out.println("CAS 操作失败,尝试退避...");
                    backoff.backoff();
                } else {
                    System.out.println("CAS 操作成功");
                    break;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private static boolean simulateCAS() {
        // 模拟 CAS 操作失败的概率
        return Math.random() > 0.5;
    }
}

通过以上内容,我们对原文档中的 CAS 实践进行了完善,涵盖了更多的 ABA 问题解决方案和 CAS 性能优化策略,并提供了相应的代码示例。

3.2 高性能无锁队列

自定义信号量实现

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

// 自定义信号量类
class CustomSemaphore {
    private final Sync sync;

    // 构造函数,初始化信号量许可数量
    public CustomSemaphore(int permits) {
        sync = new Sync(permits);
    }

    // 获取许可
    public void acquire() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }

    // 释放许可
    public void release() {
        sync.releaseShared(1);
    }

    // 内部同步器类,继承自 AQS
    private static final class Sync extends AbstractQueuedSynchronizer {
        Sync(int permits) {
            setState(permits);
        }

        // 获取共享资源
        @Override
        protected int tryAcquireShared(int acquires) {
            for (;;) {
                int available = getState();
                int remaining = available - acquires;
                if (remaining < 0 || compareAndSetState(available, remaining)) {
                    return remaining;
                }
            }
        }

        // 释放共享资源
        @Override
        protected boolean tryReleaseShared(int releases) {
            for (;;) {
                int current = getState();
                int next = current + releases;
                if (compareAndSetState(current, next)) {
                    return true;
                }
            }
        }
    }
}

自定义可重入读写锁实现

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

// 自定义可重入读写锁类
class CustomReadWriteLock {
    private final Sync sync = new Sync();

    // 获取读锁
    public void readLock() {
        sync.acquireShared(1);
    }

    // 释放读锁
    public void readUnlock() {
        sync.releaseShared(1);
    }

    // 获取写锁
    public void writeLock() {
        sync.acquire(1);
    }

    // 释放写锁
    public void writeUnlock() {
        sync.release(1);
    }

    // 内部同步器类,继承自 AQS
    private static final class Sync extends AbstractQueuedSynchronizer {
        private static final int SHARED_SHIFT = 16;
        private static final int SHARED_UNIT = (1 << SHARED_SHIFT);
        private static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1;
        private static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;

        // 获取共享计数
        static int sharedCount(int c) {
            return c >>> SHARED_SHIFT;
        }

        // 获取独占计数
        static int exclusiveCount(int c) {
            return c & EXCLUSIVE_MASK;
        }

        // 尝试获取共享资源
        @Override
        protected int tryAcquireShared(int unused) {
            Thread current = Thread.currentThread();
            int c = getState();
            if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current) {
                return -1;
            }
            int r = sharedCount(c);
            if (!compareAndSetState(c, c + SHARED_UNIT)) {
                return -1;
            }
            if (r == 0) {
                setExclusiveOwnerThread(null);
            }
            return 1;
        }

        // 尝试释放共享资源
        @Override
        protected boolean tryReleaseShared(int unused) {
            for (;;) {
                int c = getState();
                int nextc = c - SHARED_UNIT;
                if (compareAndSetState(c, nextc)) {
                    return nextc == 0;
                }
            }
        }

        // 尝试获取独占资源
        @Override
        protected boolean tryAcquire(int acquires) {
            Thread current = Thread.currentThread();
            int c = getState();
            int w = exclusiveCount(c);
            if (c != 0) {
                if (w == 0 || current != getExclusiveOwnerThread()) {
                    return false;
                }
                if (w + exclusiveCount(acquires) > MAX_COUNT) {
                    throw new Error("Maximum lock count exceeded");
                }
                setState(c + acquires);
                return true;
            }
            if (compareAndSetState(0, acquires)) {
                setExclusiveOwnerThread(current);
                return true;
            }
            return false;
        }

        // 尝试释放独占资源
        @Override
        protected boolean tryRelease(int releases) {
            if (!isHeldExclusively()) {
                throw new IllegalMonitorStateException();
            }
            int nextc = getState() - releases;
            boolean free = exclusiveCount(nextc) == 0;
            if (free) {
                setExclusiveOwnerThread(null);
            }
            setState(nextc);
            return free;
        }

        // 判断是否为当前线程独占
        @Override
        protected boolean isHeldExclusively() {
            return getExclusiveOwnerThread() == Thread.currentThread();
        }
    }
}

测试代码

public class AQSPracticeTest {
    public static void main(String[] args) {
        // 测试自定义信号量
        CustomSemaphore semaphore = new CustomSemaphore(2);
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + " acquired permit");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                    System.out.println(Thread.currentThread().getName() + " released permit");
                }
            }).start();
        }

        // 测试自定义可重入读写锁
        CustomReadWriteLock readWriteLock = new CustomReadWriteLock();
        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                readWriteLock.readLock();
                try {
                    System.out.println(Thread.currentThread().getName() + " acquired read lock");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    readWriteLock.readUnlock();
                    System.out.println(Thread.currentThread().getName() + " released read lock");
                }
            }).start();
        }

        new Thread(() -> {
            readWriteLock.writeLock();
            try {
                System.out.println(Thread.currentThread().getName() + " acquired write lock");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                readWriteLock.writeUnlock();
                System.out.println(Thread.currentThread().getName() + " released write lock");
            }
        }).start();
    }
}

代码解释

  1. 自定义信号量

    • CustomSemaphore 类使用 Sync 内部类继承自 AbstractQueuedSynchronizer 来实现信号量的功能。
    • acquire 方法用于获取许可,release 方法用于释放许可。
    • tryAcquireSharedtryReleaseShared 方法分别实现了获取和释放共享资源的逻辑。
  2. 自定义可重入读写锁

    • CustomReadWriteLock 类使用 Sync 内部类继承自 AbstractQueuedSynchronizer 来实现可重入读写锁的功能。
    • readLockreadUnlock 方法用于获取和释放读锁,writeLockwriteUnlock 方法用于获取和释放写锁。
    • tryAcquireSharedtryReleaseSharedtryAcquiretryRelease 方法分别实现了获取和释放共享资源、独占资源的逻辑。
  3. 测试代码

    • 创建了一个自定义信号量和一个自定义可重入读写锁,并启动多个线程来测试它们的功能。

4.2 常见问题解决方案

场景:高竞争环境下的性能瓶颈
方案

  1. 使用LongAdder替代AtomicLong
  2. 增加锁分离(如ConcurrentHashMap的分段锁)
  3. 采用无锁数据结构

场景:线程饥饿问题
方案

// 公平锁实现
public class FairLock extends AbstractQueuedSynchronizer {
    protected final boolean tryAcquire(int acquires) {
        if (!hasQueuedPredecessors() && 
            compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(Thread.currentThread());
            return true;
        }
        return false;
    }
}

五、架构演进与未来展望

5.1 Java并发模型演进

timeline
    title Java并发模型发展史
    section JDK1.5
        JUC包诞生 : AQS/CAS/Atomic
    section JDK1.7
        Fork/Join框架 : 工作窃取算法
    section JDK1.8
        CompletableFuture : 异步编程
        StampedLock : 乐观读锁
    section JDK19+
        虚拟线程 : Project Loom

5.2 新一代并发编程模式

  1. 反应式编程:Project Reactor
  2. 协程支持:Virtual Thread
  3. 无锁算法:RCU(Read-Copy-Update)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

stayhungerstayflush

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值