java AtomicLong原理解析

本文深入探讨了Java并发包中的AtomicLong类,解析其如何利用乐观锁机制提高多线程环境下的性能。通过对比悲观锁,介绍了乐观锁的工作原理,并详细分析了AtomicLong在JDK1.8中的源码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【转+原创】 AtomicLong原理解析

一 锁的机制

自从1.5后引入了Atomic+数据类型的类,具体在package java.util.concurrent.atomic包中,通过包名concurrent可以猜到,这个是线程安全的,既然线程安全可以用synchronized来解决,为什么还需要这些类呢?

乐观锁与悲观锁
独占锁是一种悲观锁,synchronized就是一种独占锁,它假设最坏的情况,并且只有在确保其它线程不会造成干扰的情况下执行,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁。而另一个更加有效的锁就是乐观锁。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。

通过上段引用我们就可以猜测到AtomicLong一定是采用了乐观锁来解决的。这也是高效率的一种手段。
说道乐观锁,以前接触的是hibernate的乐观锁:

1.1hibernate的乐观锁

hibernate乐观锁在更新一行数据的时候认为这个数据是没有其他人修改的,并且记录这个数据的版本号,经过一系列的操作后,开始更新,update tablename set a=‘1’ where id=‘10’ and version=‘10’。如果其他人修改了这条记录,那么version就会从10变成11,再次调用上个语句,肯定更新不了,这个就是乐观锁的原理。

CAS锁

要实现无锁(lock-free)的非阻塞算法有多种实现方法,其中 CAS(比较与交换,Compare and swap) 是一种有名的无锁算法。CAS, CPU指令,在大多数处理器架构,包括IA32、Space中采用的都是CAS指令,CAS的语义是“我认为V的值应该为A,如果是,那么将V的值更新为B,否则不修改并告诉V的值实际为多少”,CAS是项 乐观锁 技术,当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。CAS无锁算法的C实现如下:

do{   
       备份旧数据;  
       基于旧数据构造新数据;  
}while(!CAS( 内存地址,备份的旧数据,新数据 ))  

就是指当两者进行比较时,如果相等,则证明共享数据没有被修改,替换成新值,然后继续往下运行;如果不相等,说明共享数据已经被修改,放弃已经所做的操作,然后重新执行刚才的操作。容易看出 CAS 操作是基于共享数据不会被修改的假设,采用了类似于数据库的 commit-retry 的模式。当同步冲突出现的机会很少时,这种假设能带来较大的性能提升。

二、JDK1.8源码分析

public static void main(String[] args) {
        
        AtomicLong  atomicLong= new AtomicLong(1);
        System.out.println(atomicLong.incrementAndGet());
    }

追踪incrementAndGet

//其中valueOffset就是内存中的值,jdk1.8和1.7之前做了修改
 public final long incrementAndGet() {
        return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L;
    }

继续追踪getAndAddLong方法

 public final long getAndAddLong(Object this, long valueOffset, long step) {
        long expect;//期待的值
        do {
            //其实就是把内存中的值复制给期待的值
            expect= this.getLongVolatile(this, valueOffset);

	    //下面这while是重点,比较valueOffset是否和expect相等,如果相等认为没有其他线程改变这个值
        } while(!this.compareAndSwapLong(this, valueOffset, expect, valueOffset+ step));
        return expect;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值