第6部分-无锁编程与原子操作

第6部分:无锁编程与原子操作

核心目标

理解高性能并发机制与CAS原理。


1. CAS(Compare-And-Swap)机制

CAS基本概念

CAS(Compare-And-Swap)是一种无锁的原子操作,它比较内存中的值与期望值,如果相等则更新为新值,否则不做任何操作。CAS操作是原子性的,由CPU指令保证。

CAS操作流程

public class CASExample {
    private volatile int value = 0;
    
    // CAS操作的伪代码
    public boolean compareAndSwap(int expectedValue, int newValue) {
        // 1. 读取内存中的当前值
        int currentValue = value;
        
        // 2. 比较当前值与期望值
        if (currentValue == expectedValue) {
            // 3. 如果相等,更新为新值
            value = newValue;
            return true; // 操作成功
        } else {
            // 4. 如果不相等,操作失败
            return false; // 操作失败
        }
    }
    
    // 实际的CAS操作(使用AtomicInteger)
    private AtomicInteger atomicValue = new AtomicInteger(0);
    
    public boolean atomicCompareAndSet(int expectedValue, int newValue) {
        return atomicValue.compareAndSet(expectedValue, newValue);
    }
}

CAS的实现原理

public class CASImplementation {
    // CAS操作的底层实现(伪代码)
    public synchronized boolean cas(int[] memory, int offset, int expected, int update) {
        // 1. 读取内存地址offset处的值
        int current = memory[offset];
        
        // 2. 比较当前值与期望值
        if (current == expected) {
            // 3. 如果相等,原子性地更新为新值
            memory[offset] = update;
            return true;
        } else {
            // 4. 如果不相等,返回false
            return false;
        }
    }
    
    // 使用CPU的CAS指令(实际实现)
    public native boolean compareAndSwapInt(Object obj, long offset, int expected, int update);
}

CAS的优势与劣势

public class CASAdvantagesAndDisadvantages {
    private AtomicInteger counter = new AtomicInteger(0);
    
    // 优势1:无锁,避免线程阻塞
    public void advantage1() {
        // 传统synchronized方式
        synchronized (this) {
            counter.incrementAndGet(); // 可能阻塞
        }
        
        // CAS方式
        counter.incrementAndGet(); // 无阻塞,自旋重试
    }
    
    // 优势2:高性能,适合低竞争场景
    public void advantage2() {
        // 在低竞争情况下,CAS性能优于synchronized
        for (int i = 0; i < 1000000; i++) {
            counter.incrementAndGet();
        }
    }
    
    // 劣势1:ABA问题
    public void disadvantage1() {
        // 线程1:读取值A
        int value1 = counter.get();
        
        // 线程2:A -> B -> A
        counter.set(1);
        counter.set(0);
        
        // 线程1:CAS(A, C) 成功,但实际值已经被修改过
        counter.compareAndSet(value1, 2);
    }
    
    // 劣势2:自旋消耗CPU
    public void disadvantage2() {
        // 在高竞争情况下,CAS会不断自旋重试
        // 消耗大量CPU资源
        while (!counter.compareAndSet(0, 1)) {
            // 自旋等待
        }
    }
    
    // 劣势3:只能保证一个变量的原子性
    public void disadvantage3() {
        // 无法保证多个变量的原子性操作
        AtomicInteger a = new AtomicInteger(0);
        AtomicInteger b = new AtomicInteger(0);
        
        // 这两个操作不是原子的
        a.incrementAndGet();
        b.incrementAndGet();
    }
}

2. AtomicInteger、AtomicReference等原子类

基本原子类

import java.util.concurrent.atomic.*;

public class BasicAtomicClasses {
    // 1. AtomicInteger
    private AtomicInteger atomicInt = new AtomicInteger(0);
    
    public void atomicIntegerExample() {
        // 基本操作
        atomicInt.set(10);                    // 设置值
        int value = atomicInt.get();          // 获取值
        atomicInt.lazySet(20);                // 延迟设置(不保证立即可见)
        
        // 原子操作
        int oldValue = atomicInt.getAndSet(30); // 获取并设置
        int newValue = atomicInt.incrementAndGet(); // 自增并获取
        int currentValue = atomicInt.getAndIncrement(); // 获取并自增
        
        // CAS操作
        boolean success = atomicInt.compareAndSet(30, 40);
        boolean weakSuccess = atomicInt.weakCompareAndSet(40, 50);
        
        // 原子更新
        int result = atomicInt.updateAndGet(x -> x * 2);
        int result2 = atomicInt.getAndUpdate(x -> x + 1);
    }
    
    // 2. AtomicLong
    private AtomicLong atomicLong = new AtomicLong(0L);
    
    public void atomicLongExample() {
        atomicLong.set(100L);
        long value = atomicLong.get();
        atomicLong.incrementAndGet();
        atomicLong.addAndGet(50L);
    }
    
    // 3. AtomicBoolean
    private AtomicBoolean atomicBoolean = new AtomicBoolean(false);
    
    public void atomicBooleanExample() {
        atomicBoolean.set(true);
        boolean value = atomicBoolean.get();
        boolean oldValue = atomicBoolean.getAndSet(false);
        boolean success = atomicBoolean.compareAndSet(false, true);
    }
}

引用类型原子类

public class ReferenceAtomicClasses {
    // 1. AtomicReference
    private AtomicReference<String> atomicRef = new AtomicReference<>("initial");
    
    public void atomicReferenceExample() {
        // 基本操作
        atomicRef.set("new value");
        String value = atomicRef.get();
        
        // CAS操作
        boolean success = atomicRef.compareAndSet("new value", "updated value");
        
        // 原子更新
        String result = atomicRef.updateAndGet(s -> s.toUpperCase());
        String result2 = atomicRef.getAndUpdate(s -> s + "!");
    }
    
    // 2. AtomicStampedReference(解决ABA问题)
    private AtomicStampedReference<String> atomicStampedRef = 
        new AtomicStampedReference<>("initial", 0);
    
    public void atomicStampedReferenceExample() {
        String reference = atomicStampedRef.getReference();
        int stamp = atomicStampedRef.getStamp();
        
        // 带版本号的CAS操作
        boolean success = atomicStampedRef.compareAndSet(
            "initial", "new value", 0, 1);
        
        // 获取引用和版本号
        int[] stampHolder = new int[1];
        String ref = atomicStampedRef.get(stampHolder);
        int currentStamp = stampHolder[0];
    }
    
    // 3. AtomicMarkableReference
    private AtomicMarkableReference<String> atomicMarkableRef = 
        new AtomicMarkableReference<>("initial", false);
    
    public void atomicMarkableReferenceExample() {
        boolean[] markHolder = new boolean[1];
        String ref = atomicMarkableRef.get(markHolder);
        boolean marked = markHolder[0];
        
        // 带标记的CAS操作
        boolean success = atomicMarkableRef.compareAndSet(
            "initial", "new value", false, true);
    }
}

数组原子类

public class ArrayAtomicClasses {
    // 1. AtomicIntegerArray
    private AtomicIntegerArray atomicIntArray = new AtomicIntegerArray(10);
    
    public void atomicIntegerArrayExample() {
        // 基本操作
        atomicIntArray.set(0, 100);
        int value = atomicIntArray.get(0);
        
        // 原子操作
        int oldValue = atomicIntArray.getAndSet(0, 200);
        int newValue = atomicIntArray.incrementAndGet(0);
        
        // CAS操作
        boolean success = atomicIntArray.compareAndSet(0, 200, 300);
        
        // 原子更新
        int result = atomicIntArray.updateAndGet(0, x -> x * 2);
    }
    
    // 2. AtomicLongArray
    private AtomicLongArray atomicLongArray = new AtomicLongArray(5);
    
    public void atomicLongArrayExample() {
        atomicLongArray.set(0, 1000L);
        long value = atomicLongArray.get(0);
        atomicLongArray.addAndGet(0, 500L);
    }
    
    // 3. AtomicReferenceArray
    private AtomicReferenceArray<String> atomicRefArray = 
        new AtomicReferenceArray<>(10);
    
    public void atomicReferenceArrayExample() {
        atomicRefArray.set(0, "hello");
        String value = atomicRefArray.get(0);
        boolean success = atomicRefArray.compareAndSet(0, "hello", "world");
    }
}

字段更新器

public class FieldUpdaterClasses {
    private volatile int field = 0;
    private volatile String stringField = "initial";
    
    // 1. AtomicIntegerFieldUpdater
    private static final AtomicIntegerFieldUpdater<FieldUpdaterClasses> fieldUpdater =
        AtomicIntegerFieldUpdater.newUpdater(FieldUpdaterClasses.class, "field");
    
    public void atomicIntegerFieldUpdaterExample() {
        // 更新volatile字段
        fieldUpdater.set(this, 100);
        int value = fieldUpdater.get(this);
        
        // 原子操作
        int oldValue = fieldUpdater.getAndSet(this, 200);
        int newValue = fieldUpdater.incrementAndGet(this);
        
        // CAS操作
        boolean success = fieldUpdater.compareAndSet(this, 200, 300);
    }
    
    // 2. AtomicReferenceFieldUpdater
    private static final AtomicReferenceFieldUpdater<FieldUpdaterClasses, String> refFieldUpdater =
        AtomicReferenceFieldUpdater.newUpdater(FieldUpdaterClasses.class, String.class, "stringField");
    
    public void atomicReferenceFieldUpdaterExample() {
        refFieldUpdater.set(this, "new value");
        String value = refFieldUpdater.get(this);
        
        boolean success = refFieldUpdater.compareAndSet(this, "new value", "updated value");
    }
}

3. ABA问题与AtomicStampedReference

ABA问题详解

public class ABAProblem {
    private AtomicReference<String> atomicRef = new AtomicReference<>("A");
    
    public void demonstrateABAProblem() throws InterruptedException {
        // 线程1:读取值A
        Thread thread1 = new Thread(() -> {
            String value = atomicRef.get();
            System.out.println("线程1读取到: " + value);
            
            try {
                Thread.sleep(1000); // 模拟处理时间
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            
            // 尝试将A改为C
            boolean success = atomicRef.compareAndSet(value, "C");
            System.out.println("线程1 CAS结果: " + success);
        });
        
        // 线程2:A -> B -> A
        Thread thread2 = new Thread(() -> {
            try {
                Thread.sleep(500); // 等待线程1读取值
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            
            // A -> B
            atomicRef.compareAndSet("A", "B");
            System.out.println("线程2: A -> B");
            
            // B -> A
            atomicRef.compareAndSet("B", "A");
            System.out.println("线程2: B -> A");
        });
        
        thread1.start();
        thread2.start();
        
        thread1.join();
        thread2.join();
        
        System.out.println("最终值: " + atomicRef.get());
    }
}

使用AtomicStampedReference解决ABA问题

public class ABAProblemSolution {
    private AtomicStampedReference<String> atomicStampedRef = 
        new AtomicStampedReference<>("A", 0);
    
    public void solveABAProblem() throws InterruptedException {
        // 线程1:读取值A和版本号
        Thread thread1 = new Thread(() -> {
            int[] stampHolder = new int[1];
            String value = atomicStampedRef.get(stampHolder);
            int stamp = stampHolder[0];
            
            System.out.println("线程1读取到: " + value + ", 版本: " + stamp);
            
            try {
                Thread.sleep(1000); // 模拟处理时间
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            
            // 尝试将A改为C,版本号必须匹配
            boolean success = atomicStampedRef.compareAndSet(value, "C", stamp, stamp + 1);
            System.out.println("线程1 CAS结果: " + success);
        });
        
        // 线程2:A -> B -> A,版本号会改变
        Thread thread2 = new Thread(() -> {
            try {
                Thread.sleep(500); // 等待线程1读取值
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            
            // A -> B,版本号从0变为1
            atomicStampedRef.compareAndSet("A", "B", 0, 1);
            System.out.println("线程2: A -> B, 版本: 0 -> 1");
            
            // B -> A,版本号从1变为2
            atomicStampedRef.compareAndSet("B", "A", 1, 2);
            System.out.println("线程2: B -> A, 版本: 1 -> 2");
        });
        
        thread1.start();
        thread2.start();
        
        thread1.join();
        thread2.join();
        
        int[] stampHolder = new int[1];
        String finalValue = atomicStampedRef.get(stampHolder);
        int finalStamp = stampHolder[0];
        System.out.println("最终值: " + finalValue + ", 版本: " + finalStamp);
    }
}

版本号机制

public class VersionMechanism {
    private AtomicStampedReference<Integer> versionedRef = 
        new AtomicStampedReference<>(0, 0);
    
    public void versionMechanismExample() {
        // 模拟多次修改
        for (int i = 0; i < 5; i++) {
            int[] stampHolder = new int[1];
            Integer currentValue = versionedRef.get(stampHolder);
            int currentStamp = stampHolder[0];
            
            // 更新值和版本号
            boolean success = versionedRef.compareAndSet(
                currentValue, 
                currentValue + 1, 
                currentStamp, 
                currentStamp + 1
            );
            
            System.out.println("更新 " + i + ": " + success + 
                             ", 值: " + versionedRef.getReference() + 
                             ", 版本: " + versionedRef.getStamp());
        }
    }
    
    // 检查值是否被修改过
    public boolean hasValueChanged(int expectedValue, int expectedStamp) {
        int[] stampHolder = new int[1];
        Integer currentValue = versionedRef.get(stampHolder);
        int currentStamp = stampHolder[0];
        
        return currentValue != expectedValue || currentStamp != expectedStamp;
    }
}

4. LongAdder、DoubleAdder原理

LongAdder原理

import java.util.concurrent.atomic.LongAdder;

public class LongAdderExample {
    private LongAdder longAdder = new LongAdder();
    
    public void longAdderBasicUsage() {
        // 基本操作
        longAdder.add(10);           // 增加10
        longAdder.increment();       // 增加1
        longAdder.decrement();       // 减少1
        longAdder.add(-5);           // 减少5
        
        // 获取值
        long sum = longAdder.sum();  // 获取当前总和
        longAdder.reset();           // 重置为0
        long sumAfterReset = longAdder.sum();
        
        System.out.println("总和: " + sum);
        System.out.println("重置后: " + sumAfterReset);
    }
    
    // LongAdder vs AtomicLong性能对比
    public void performanceComparison() throws InterruptedException {
        int threadCount = 10;
        int operationsPerThread = 100000;
        
        // 测试AtomicLong
        AtomicLong atomicLong = new AtomicLong(0);
        long start = System.currentTimeMillis();
        
        Thread[] atomicThreads = new Thread[threadCount];
        for (int i = 0; i < threadCount; i++) {
            atomicThreads[i] = new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    atomicLong.incrementAndGet();
                }
            });
            atomicThreads[i].start();
        }
        
        for (Thread thread : atomicThreads) {
            thread.join();
        }
        
        long atomicTime = System.currentTimeMillis() - start;
        System.out.println("AtomicLong时间: " + atomicTime + "ms, 结果: " + atomicLong.get());
        
        // 测试LongAdder
        LongAdder longAdder = new LongAdder();
        start = System.currentTimeMillis();
        
        Thread[] adderThreads = new Thread[threadCount];
        for (int i = 0; i < threadCount; i++) {
            adderThreads[i] = new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    longAdder.increment();
                }
            });
            adderThreads[i].start();
        }
        
        for (Thread thread : adderThreads) {
            thread.join();
        }
        
        long adderTime = System.currentTimeMillis() - start;
        System.out.println("LongAdder时间: " + adderTime + "ms, 结果: " + longAdder.sum());
    }
}

LongAdder内部原理

public class LongAdderInternalPrinciple {
    // LongAdder内部结构(简化版)
    private static class LongAdderInternal {
        private volatile long base;           // 基础值
        private volatile Cell[] cells;        // 分段计数器数组
        private volatile int cellsBusy;       // 数组扩容标志
        
        // 内部Cell类
        private static class Cell {
            volatile long value;
            Cell(long x) { value = x; }
        }
        
        // 增加操作
        public void add(long x) {
            Cell[] as = cells;
            if (as == null) {
                // 如果cells为null,尝试更新base
                if (casBase(base, base + x)) {
                    return;
                }
                // 如果更新base失败,初始化cells
                if (cells == null) {
                    initCells();
                }
            }
            
            // 使用cells进行分段计数
            int index = getProbe() & (as.length - 1);
            Cell cell = as[index];
            if (cell == null) {
                if (cellsBusy == 0) {
                    Cell newCell = new Cell(x);
                    if (cellsBusy == 0 && casCellsBusy()) {
                        try {
                            if (cells[index] == null) {
                                cells[index] = newCell;
                                return;
                            }
                        } finally {
                            cellsBusy = 0;
                        }
                    }
                }
                add(x); // 重试
            } else {
                if (cell.cas(cell.value, cell.value + x)) {
                    return;
                }
                add(x); // 重试
            }
        }
        
        // 获取总和
        public long sum() {
            long sum = base;
            Cell[] as = cells;
            if (as != null) {
                for (Cell cell : as) {
                    if (cell != null) {
                        sum += cell.value;
                    }
                }
            }
            return sum;
        }
        
        // CAS操作(伪代码)
        private boolean casBase(long expected, long update) {
            // 使用CAS更新base值
            return true; // 简化实现
        }
        
        private boolean casCellsBusy() {
            // 使用CAS设置cellsBusy标志
            return true; // 简化实现
        }
        
        private void initCells() {
            // 初始化cells数组
        }
        
        private int getProbe() {
            // 获取线程的探针值
            return Thread.currentThread().hashCode();
        }
    }
}

DoubleAdder使用

import java.util.concurrent.atomic.DoubleAdder;

public class DoubleAdderExample {
    private DoubleAdder doubleAdder = new DoubleAdder();
    
    public void doubleAdderUsage() {
        // 基本操作
        doubleAdder.add(10.5);       // 增加10.5
        doubleAdder.add(-3.2);       // 减少3.2
        
        // 获取值
        double sum = doubleAdder.sum();
        doubleAdder.reset();
        
        System.out.println("总和: " + sum);
    }
    
    // 性能测试
    public void performanceTest() throws InterruptedException {
        int threadCount = 10;
        int operationsPerThread = 100000;
        
        DoubleAdder doubleAdder = new DoubleAdder();
        long start = System.currentTimeMillis();
        
        Thread[] threads = new Thread[threadCount];
        for (int i = 0; i < threadCount; i++) {
            threads[i] = new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    doubleAdder.add(1.0);
                }
            });
            threads[i].start();
        }
        
        for (Thread thread : threads) {
            thread.join();
        }
        
        long time = System.currentTimeMillis() - start;
        System.out.println("DoubleAdder时间: " + time + "ms, 结果: " + doubleAdder.sum());
    }
}

5. 无锁队列(ConcurrentLinkedQueue)

ConcurrentLinkedQueue基本用法

import java.util.concurrent.ConcurrentLinkedQueue;

public class ConcurrentLinkedQueueExample {
    private ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
    
    public void basicUsage() {
        // 添加元素
        queue.offer("item1");
        queue.offer("item2");
        queue.offer("item3");
        
        // 获取并移除元素
        String item = queue.poll();
        System.out.println("取出: " + item);
        
        // 获取但不移除元素
        String peekItem = queue.peek();
        System.out.println("查看: " + peekItem);
        
        // 检查是否为空
        boolean isEmpty = queue.isEmpty();
        System.out.println("是否为空: " + isEmpty);
        
        // 获取大小(注意:这个操作是O(n)的)
        int size = queue.size();
        System.out.println("大小: " + size);
    }
    
    // 生产者-消费者模式
    public void producerConsumerExample() throws InterruptedException {
        ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<>();
        
        // 生产者
        Thread producer = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                queue.offer(i);
                System.out.println("生产: " + i);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        // 消费者
        Thread consumer = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                Integer item = queue.poll();
                if (item != null) {
                    System.out.println("消费: " + item);
                }
                try {
                    Thread.sleep(150);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        producer.start();
        consumer.start();
        
        producer.join();
        consumer.join();
    }
}

无锁队列的实现原理

public class LockFreeQueueImplementation {
    // 无锁队列的节点
    private static class Node<T> {
        volatile T item;
        volatile Node<T> next;
        
        Node(T item) {
            this.item = item;
        }
    }
    
    // 无锁队列实现(简化版)
    private static class LockFreeQueue<T> {
        private volatile Node<T> head;
        private volatile Node<T> tail;
        
        public LockFreeQueue() {
            Node<T> dummy = new Node<>(null);
            head = dummy;
            tail = dummy;
        }
        
        // 入队操作
        public boolean offer(T item) {
            Node<T> newNode = new Node<>(item);
            
            while (true) {
                Node<T> last = tail;
                Node<T> next = last.next;
                
                if (last == tail) {
                    if (next == null) {
                        // 尝试将新节点链接到最后一个节点
                        if (casNext(last, next, newNode)) {
                            // 更新tail指针
                            casTail(tail, newNode);
                            return true;
                        }
                    } else {
                        // 帮助其他线程推进tail指针
                        casTail(tail, next);
                    }
                }
            }
        }
        
        // 出队操作
        public T poll() {
            while (true) {
                Node<T> first = head;
                Node<T> last = tail;
                Node<T> next = first.next;
                
                if (first == head) {
                    if (first == last) {
                        if (next == null) {
                            return null; // 队列为空
                        }
                        // 帮助推进tail指针
                        casTail(last, next);
                    } else {
                        T item = next.item;
                        if (item != null) {
                            next.item = null;
                            casHead(first, next);
                            return item;
                        }
                    }
                }
            }
        }
        
        // CAS操作(伪代码)
        private boolean casNext(Node<T> node, Node<T> expected, Node<T> update) {
            // 使用CAS更新next指针
            return true; // 简化实现
        }
        
        private boolean casTail(Node<T> expected, Node<T> update) {
            // 使用CAS更新tail指针
            return true; // 简化实现
        }
        
        private boolean casHead(Node<T> expected, Node<T> update) {
            // 使用CAS更新head指针
            return true; // 简化实现
        }
    }
}

性能对比

public class QueuePerformanceComparison {
    public void performanceTest() throws InterruptedException {
        int threadCount = 10;
        int operationsPerThread = 100000;
        
        // 测试ConcurrentLinkedQueue
        ConcurrentLinkedQueue<Integer> concurrentQueue = new ConcurrentLinkedQueue<>();
        long start = System.currentTimeMillis();
        
        Thread[] concurrentThreads = new Thread[threadCount];
        for (int i = 0; i < threadCount; i++) {
            concurrentThreads[i] = new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    concurrentQueue.offer(j);
                    concurrentQueue.poll();
                }
            });
            concurrentThreads[i].start();
        }
        
        for (Thread thread : concurrentThreads) {
            thread.join();
        }
        
        long concurrentTime = System.currentTimeMillis() - start;
        System.out.println("ConcurrentLinkedQueue时间: " + concurrentTime + "ms");
        
        // 测试synchronized队列
        Queue<Integer> synchronizedQueue = new LinkedList<>();
        Object lock = new Object();
        start = System.currentTimeMillis();
        
        Thread[] syncThreads = new Thread[threadCount];
        for (int i = 0; i < threadCount; i++) {
            syncThreads[i] = new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    synchronized (lock) {
                        synchronizedQueue.offer(j);
                        synchronizedQueue.poll();
                    }
                }
            });
            syncThreads[i].start();
        }
        
        for (Thread thread : syncThreads) {
            thread.join();
        }
        
        long syncTime = System.currentTimeMillis() - start;
        System.out.println("Synchronized队列时间: " + syncTime + "ms");
    }
}

6. StampedLock与读写锁优化

StampedLock基本用法

import java.util.concurrent.locks.StampedLock;

public class StampedLockExample {
    private final StampedLock stampedLock = new StampedLock();
    private int value = 0;
    
    // 写操作
    public void write(int newValue) {
        long stamp = stampedLock.writeLock();
        try {
            value = newValue;
            System.out.println("写入: " + newValue);
        } finally {
            stampedLock.unlockWrite(stamp);
        }
    }
    
    // 读操作(悲观读)
    public int read() {
        long stamp = stampedLock.readLock();
        try {
            System.out.println("读取: " + value);
            return value;
        } finally {
            stampedLock.unlockRead(stamp);
        }
    }
    
    // 乐观读
    public int optimisticRead() {
        long stamp = stampedLock.tryOptimisticRead();
        int currentValue = value;
        
        if (!stampedLock.validate(stamp)) {
            // 乐观读失败,升级为悲观读
            stamp = stampedLock.readLock();
            try {
                currentValue = value;
            } finally {
                stampedLock.unlockRead(stamp);
            }
        }
        
        System.out.println("乐观读取: " + currentValue);
        return currentValue;
    }
    
    // 读锁升级为写锁
    public void readToWriteUpgrade() {
        long stamp = stampedLock.readLock();
        try {
            while (value == 0) {
                long writeStamp = stampedLock.tryConvertToWriteLock(stamp);
                if (writeStamp != 0) {
                    stamp = writeStamp;
                    value = 42;
                    break;
                } else {
                    stampedLock.unlockRead(stamp);
                    stamp = stampedLock.writeLock();
                }
            }
        } finally {
            stampedLock.unlock(stamp);
        }
    }
}

StampedLock vs ReentrantReadWriteLock

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class StampedLockVsReadWriteLock {
    private final StampedLock stampedLock = new StampedLock();
    private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private int value = 0;
    
    // StampedLock实现
    public void stampedLockWrite(int newValue) {
        long stamp = stampedLock.writeLock();
        try {
            value = newValue;
        } finally {
            stampedLock.unlockWrite(stamp);
        }
    }
    
    public int stampedLockRead() {
        long stamp = stampedLock.readLock();
        try {
            return value;
        } finally {
            stampedLock.unlockRead(stamp);
        }
    }
    
    // ReentrantReadWriteLock实现
    public void readWriteLockWrite(int newValue) {
        readWriteLock.writeLock().lock();
        try {
            value = newValue;
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }
    
    public int readWriteLockRead() {
        readWriteLock.readLock().lock();
        try {
            return value;
        } finally {
            readWriteLock.readLock().unlock();
        }
    }
    
    // 性能对比
    public void performanceComparison() throws InterruptedException {
        int threadCount = 10;
        int operationsPerThread = 100000;
        
        // 测试StampedLock
        long start = System.currentTimeMillis();
        Thread[] stampedThreads = new Thread[threadCount];
        for (int i = 0; i < threadCount; i++) {
            stampedThreads[i] = new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    if (j % 10 == 0) {
                        stampedLockWrite(j);
                    } else {
                        stampedLockRead();
                    }
                }
            });
            stampedThreads[i].start();
        }
        
        for (Thread thread : stampedThreads) {
            thread.join();
        }
        
        long stampedTime = System.currentTimeMillis() - start;
        System.out.println("StampedLock时间: " + stampedTime + "ms");
        
        // 测试ReentrantReadWriteLock
        start = System.currentTimeMillis();
        Thread[] readWriteThreads = new Thread[threadCount];
        for (int i = 0; i < threadCount; i++) {
            readWriteThreads[i] = new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    if (j % 10 == 0) {
                        readWriteLockWrite(j);
                    } else {
                        readWriteLockRead();
                    }
                }
            });
            readWriteThreads[i].start();
        }
        
        for (Thread thread : readWriteThreads) {
            thread.join();
        }
        
        long readWriteTime = System.currentTimeMillis() - start;
        System.out.println("ReentrantReadWriteLock时间: " + readWriteTime + "ms");
    }
}

乐观读的使用场景

public class OptimisticReadExample {
    private final StampedLock stampedLock = new StampedLock();
    private int value = 0;
    private long lastModified = 0;
    
    // 写操作
    public void write(int newValue) {
        long stamp = stampedLock.writeLock();
        try {
            value = newValue;
            lastModified = System.currentTimeMillis();
        } finally {
            stampedLock.unlockWrite(stamp);
        }
    }
    
    // 乐观读操作
    public int optimisticRead() {
        long stamp = stampedLock.tryOptimisticRead();
        int currentValue = value;
        long currentLastModified = lastModified;
        
        // 验证读操作期间是否有写操作
        if (!stampedLock.validate(stamp)) {
            // 乐观读失败,升级为悲观读
            stamp = stampedLock.readLock();
            try {
                currentValue = value;
                currentLastModified = lastModified;
            } finally {
                stampedLock.unlockRead(stamp);
            }
        }
        
        return currentValue;
    }
    
    // 条件性读操作
    public int conditionalRead(int expectedValue) {
        long stamp = stampedLock.tryOptimisticRead();
        int currentValue = value;
        
        if (currentValue == expectedValue && stampedLock.validate(stamp)) {
            return currentValue;
        }
        
        // 乐观读失败或条件不满足,使用悲观读
        stamp = stampedLock.readLock();
        try {
            currentValue = value;
            return currentValue;
        } finally {
            stampedLock.unlockRead(stamp);
        }
    }
}

实践练习

练习1:无锁计数器实现

public class LockFreeCounter {
    private final AtomicInteger counter = new AtomicInteger(0);
    
    public void increment() {
        counter.incrementAndGet();
    }
    
    public void decrement() {
        counter.decrementAndGet();
    }
    
    public int get() {
        return counter.get();
    }
    
    public void add(int delta) {
        counter.addAndGet(delta);
    }
    
    // 测试方法
    public static void main(String[] args) throws InterruptedException {
        LockFreeCounter counter = new LockFreeCounter();
        int threadCount = 10;
        int operationsPerThread = 100000;
        
        Thread[] threads = new Thread[threadCount];
        for (int i = 0; i < threadCount; i++) {
            threads[i] = new Thread(() -> {
                for (int j = 0; j < operationsPerThread; j++) {
                    counter.increment();
                }
            });
            threads[i].start();
        }
        
        for (Thread thread : threads) {
            thread.join();
        }
        
        System.out.println("期望结果: " + (threadCount * operationsPerThread));
        System.out.println("实际结果: " + counter.get());
    }
}

练习2:无锁栈实现

public class LockFreeStack<T> {
    private static class Node<T> {
        final T item;
        volatile Node<T> next;
        
        Node(T item) {
            this.item = item;
        }
    }
    
    private volatile Node<T> head;
    
    public void push(T item) {
        Node<T> newNode = new Node<>(item);
        Node<T> currentHead;
        
        do {
            currentHead = head;
            newNode.next = currentHead;
        } while (!casHead(currentHead, newNode));
    }
    
    public T pop() {
        Node<T> currentHead;
        Node<T> newHead;
        
        do {
            currentHead = head;
            if (currentHead == null) {
                return null;
            }
            newHead = currentHead.next;
        } while (!casHead(currentHead, newHead));
        
        return currentHead.item;
    }
    
    public boolean isEmpty() {
        return head == null;
    }
    
    // CAS操作(伪代码)
    private boolean casHead(Node<T> expected, Node<T> update) {
        // 使用AtomicReferenceFieldUpdater或Unsafe实现
        return true; // 简化实现
    }
}

总结

本部分深入介绍了无锁编程与原子操作的核心概念:

  1. CAS机制:理解无锁编程的基础
  2. 原子类:掌握各种原子类的使用方法
  3. ABA问题:了解并解决ABA问题
  4. LongAdder:学习分段计数器的原理
  5. 无锁队列:理解无锁数据结构的实现
  6. StampedLock:掌握读写锁的优化

这些技术是构建高性能并发系统的重要工具,下一部分将学习Fork/Join框架与并行流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

谁在黄金彼岸

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

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

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

打赏作者

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

抵扣说明:

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

余额充值