JDK源码

java.util.concurrent

以下是atomic包下的

AtomicInteger

Unsafe类:提供的方法可以直接访问内存、线程。

属性:Unsafe、int value

通过Unsafe方法中的CAS循环,保证int类型值的原子操作

java 复制代码
int var5;
do {
    var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;

AtomicInteger

属性:Unsafe、int value 0、1代表true、false

保证boolean类型值的原子操作

AtomicIntegerArray

属性:Unsafe、int[] array

保证int[]数组中的每一个索引元素的原子操作

AtomicMarkableReference

保证对一个对象和一个boolean类型的标识符的原子操作。

java 复制代码
A initialRef = new A();
boolean initialMark = false;
AtomicMarkableReference<A> amr = new AtomicMarkableReference<>(initialRef, initialMark);
boolean[] markHolder = new boolean[1];
A expectedReference = amr.get(markHolder); // amr中的对象引用
boolean expectedMark = markHolder[0]; // amr中的标识符
A newReference = new A();
boolean newMark = true;
System.out.println(amr.compareAndSet(expectedReference, newReference, expectedMark, newMark));

AtomicReference

实现对一个对象引用的原子操作。

java 复制代码
AtomicReference<A> ar = new AtomicReference<>();
A origin = ar.get();
// origin = new A();
A newA = new A();
System.out.println(ar.compareAndSet(origin, newA));

AtomicStampedReference

实现对对象引用和int类型的版本戳的原子操作,

解决ABA问题(A修改为B,再修改回A,另一个线程的CAS误认为A没有修改,导致CAS成功)

java 复制代码
A initialRef = new A();
int initialStamp = 0;
AtomicStampedReference<A> asr = new AtomicStampedReference<>(initialRef, initialStamp);
int[] stampHolder = new int[1];
A expectedReference = asr.get(stampHolder);
int expectedStamp = stampHolder[0];
A newReference = new A();
int newStamp = expectedStamp + 1;
System.out.println(asr.compareAndSet(expectedReference, newReference, expectedStamp, newStamp));

LongAdder

以空间换时间,内部有多个单元格数组,add时,可能在数组的不同位置进行CAS,避免了CAS的冲突,提高的CAS的成功率。

相较于AtomicInteger,性能高、但内存开销大。

java 复制代码
ExecutorService threadPool = Executors.newFixedThreadPool(5);
CountDownLatch countDownLatch = new CountDownLatch(5);
for (int i = 0; i < 5; i++) {
 threadPool.execute(() -> {
     for (int j = 0; j < 100000; j++) {
         la.increment();
     }
     countDownLatch.countDown();
 });
}
countDownLatch.await();
System.out.println(la.sum());
System.out.println(la.intValue());

一下是locks包下的

ReentrantLock

TODO:JRB 原理

java 复制代码
static int num = 0;
static ReentrantLock rl = new ReentrantLock();

public static void main(String[] args) throws InterruptedException {
    ExecutorService threadPool = Executors.newFixedThreadPool(5);
    CountDownLatch countDownLatch = new CountDownLatch(2);
    threadPool.execute(() -> {
        rl.lock();
        try {
            TimeUnit.SECONDS.sleep(3); // 保证第二个线程的tryLock失败
            num++;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            rl.unlock();
        }
        countDownLatch.countDown();
        ;
    });
    threadPool.execute(() -> {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try {
            if (rl.tryLock(1, TimeUnit.SECONDS)) {
                try {
                    num++;
                } finally {
                    rl.unlock();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        countDownLatch.countDown();
    });
    countDownLatch.await();
    System.out.println(num);
}

Condition

实现等待通知机制。

java 复制代码
public class MyTest {

    static ReentrantLock reentrantLock = new ReentrantLock();
    static Condition condition = reentrantLock.newCondition();
    static int num = 1;

    public static void main(String[] args) throws InterruptedException {
        // 两个线程交替打印
        two();
    }

    private static void two() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            for (int i = 1; i < 100; i++) {
                reentrantLock.lock();
                try {
                    while (num % 2 == 0) {
                        condition.await(); // 释放锁并等待
                    }
                    System.out.println("线程1===>" + i);
                    condition.signalAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    reentrantLock.unlock();
                }
            }
        });
        Thread t2 = new Thread(() -> {
            for (int i = 1; i < 100; i++) {
                reentrantLock.lock();
                try {
                    while (num % 1 == 0) {
                        condition.await(); // 释放锁并等待 
                    }
                    System.out.println("线程2===>" + i);
                    condition.signalAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    reentrantLock.unlock();
                }
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("END");
    }
}

ReentrantReadWriteLock

用于优化读多写少场景下的性能。

读写锁不能被同时拥有。

在没有线程拥有写锁的前提下,多个线程可以同时拥有读锁。

在没有线程拥有读锁的前提下,只能有一个线程拥有写锁。

存在问题:拥有读锁不断被使用,导致写锁可能长时间无法获取。

java 复制代码
public class MyTest {

    static int num = 0;
    static ReentrantReadWriteLock rrwl = new ReentrantReadWriteLock();
    static ReentrantReadWriteLock.ReadLock readLock = rrwl.readLock();
    static ReentrantReadWriteLock.WriteLock writeLock = rrwl.writeLock();

    public static void main(String[] args) throws InterruptedException {
        ExecutorService threadPool = Executors.newFixedThreadPool(5);
        CountDownLatch countDownLatch = new CountDownLatch(3);
        threadPool.execute(() -> {
            readLock.lock();
            try {
                TimeUnit.SECONDS.sleep(4);
                System.out.println("线程1==>" + num);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                readLock.unlock();
            }
            countDownLatch.countDown();
        });
        threadPool.execute(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                if (readLock.tryLock(1, TimeUnit.SECONDS)) {
                    try {
                        System.out.println("线程2==>" + num);
                    } finally {
                        readLock.unlock();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            countDownLatch.countDown();
        });
        threadPool.execute(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                if (writeLock.tryLock(1, TimeUnit.SECONDS)) {
                    try {
                        num++;
                    } finally {
                        writeLock.unlock();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            countDownLatch.countDown();
        });
        countDownLatch.await();
        System.out.println(num);
    }
}

StampedLock

读写锁,与ReentrantReadWriteLock的区别是提供一种新的读锁:乐观读锁。

获取乐观读锁的操作并不会阻塞其他线程获取读锁,但是我们要校验读锁的有效性,即中间是否有其他线程获取了写锁,如果有,再尝试获取读锁。

java 复制代码
public class MyTest {

    static int num = 0;
    static StampedLock sl = new StampedLock();

    public static void main(String[] args) throws InterruptedException {
        ExecutorService threadPool = Executors.newFixedThreadPool(5);
        CountDownLatch countDownLatch = new CountDownLatch(3);
        threadPool.execute(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            long stamp = sl.tryOptimisticRead();
            if (!sl.validate(stamp)) {
                stamp = sl.readLock();
                try {
                    System.out.println(stamp + "悲观线程1===>" + num);

                } finally {
                    sl.unlockRead(stamp);
                }
            } else {
                System.out.println(stamp + "线程1===>" + num);
            }
            countDownLatch.countDown();
            /*long stamp = sl.readLock();
            try {
                TimeUnit.SECONDS.sleep(4);
                System.out.println(stamp + "线程1===>" + num);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                sl.unlockRead(stamp);
            }
            countDownLatch.countDown();*/
        });
        threadPool.execute(() -> {
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            long stamp = sl.tryOptimisticRead();
            if (!sl.validate(stamp)) {
                stamp = sl.readLock();
                try {
                    System.out.println(stamp + "悲观线程2===>" + num);

                } finally {
                    sl.unlockRead(stamp);
                }
            } else {
                System.out.println(stamp + "线程2===>" + num);
            }
            countDownLatch.countDown();
        });
        threadPool.execute(() -> {
            /*try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/
            long stamp = sl.writeLock();
            try {
                TimeUnit.SECONDS.sleep(2);
                num++;
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                sl.unlockWrite(stamp);
            }
            countDownLatch.countDown();
        });
        countDownLatch.await();
        System.out.println(num);
    }
}
相关推荐
小厂永远得不到的男人9 分钟前
基于 Spring Validation 实现全局参数校验异常处理
java·后端·架构
计算机编程小咖1 小时前
《基于大数据的农产品交易数据分析与可视化系统》选题不当,毕业答辩可能直接挂科
java·大数据·hadoop·python·数据挖掘·数据分析·spark
艾莉丝努力练剑1 小时前
【C语言16天强化训练】从基础入门到进阶:Day 7
java·c语言·学习·算法
老华带你飞1 小时前
校园交友|基于SprinBoot+vue的校园交友网站(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·校园交友网站
自强的小白2 小时前
学习Java24天
java·学习
Ashlee_code3 小时前
香港券商櫃台系統跨境金融研究
java·python·科技·金融·架构·系统架构·区块链
还梦呦3 小时前
2025年09月计算机二级Java选择题每日一练——第五期
java·开发语言·计算机二级
2501_924890523 小时前
商超场景徘徊识别误报率↓79%!陌讯多模态时序融合算法落地优化
java·大数据·人工智能·深度学习·算法·目标检测·计算机视觉
從南走到北4 小时前
JAVA国际版东郊到家同城按摩服务美容美发私教到店服务系统源码支持Android+IOS+H5
android·java·开发语言·ios·微信·微信小程序·小程序
qianmoq4 小时前
第04章:数字流专题:IntStream让数学计算更简单
java