我理解的线程并发-CAS

java 多线程并发时有各种资源争抢问题,怎么处理资源争抢呢?

a.独占式,表现为不可重入锁或者互斥锁/独占锁/悲观锁

使用关键字synchronized,通过它可以完成代码块或函数的独占,当一个线程执行到synchronized标识的代码块时,另一个线程也执行到此处,必须等待上一个线程执行完毕释放锁才能获得锁而继续执行。

b.共享式,表现为可重入锁或者乐观锁/共享锁,

通过使用java CAS来完成共享锁的原子操作,操作是非阻塞的。
CAS原理:
sun.misc.Unsafe.compareAndSwapInt(Object paramObject, long valueOffset, int expect, int update)函数,基于硬件来实现的。函数native实现。本意为比较并交换。 4个参数,
paramObject:需要改变的对象,也就是当前封装value的对象
valueOffset:当前封装的value内存汇编偏移量,c++本地函数可以根据汇编偏移量获取真实的内存地址。
expect: 旧的预期值,一般从当前对象获取的瞬时值。
update:即将更新value的值
当且仅当旧预期值expect和valueOffset内存地址上的值相同时,将value修改为update值并返回true,否则什么都不做,并返回false。

该方法的实现位于unsafe.cpp中

UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
  UnsafeWrapper("Unsafe_CompareAndSwapInt");
  oop p = JNIHandles::resolve(obj);
  jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
  return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
UNSAFE_END

1.通过valueOffset汇编偏移量获取变量value在内存中的地址
2.然后通过Atomic::cmpxchg对比内存地址上的值和旧值,决定是否更换新值,并返回交换结果。

java实际使用的AQS java.util.concurrent.atomic包都是使用CAS实现

AtomicBoolean.class
AtomicInteger.class
AtomicIntegerArray.class
AtomicIntegerFieldUpdater.class
AtomicLong.class
AtomicLongArray.class
AtomicLongFieldUpdater.class
AtomicMarkableReference.class
AtomicReference.class
AtomicReferenceArray.class
AtomicReferenceFieldUpdater.class
AtomicStampedReference.class

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值