目 录CONTENT

文章目录

思考感悟

FatFish1
2025-08-12 / 0 评论 / 0 点赞 / 0 阅读 / 0 字 / 正在检测是否收录...

并发编程常见的几种工具

Synchronized、ReentrantLock、CAS

Synchronized锁和ReentrantLock最本质的区别是二者的实现方式:

  • Synchronized锁是通过字节码实现的,即加monitorenter和monitorexit

  • ReentrantLock是AQS的实现,其加锁的方式是基于Unsafe包下面的CAS实现的

在早期版本的JDK中,Synchronized是重量级锁,性能不佳,但是随着新版本JDK通过锁自旋、锁升级等优化,性能已经有所提升,已经不把性能作为选择锁类型的主要因素了

ReentrantLock是java代码实现锁,其底层使用的是volatile+unsafe(可见它在源码的层面上并非真正的锁),因此比Synchronized多了很多能力,包括:

  • 公平锁和非公平锁

  • 阻塞获取锁

  • 中断获取锁

  • 通过Condition实现的更灵活的条件队列

  • 丰富的api用于获取锁状态

CAS则不是锁,是unsafe包下面的一套native方法,它的含义是compareAndSet,本质上是一个原子操作,它也是ReentrantLock、ConcurrentHashMap等并发模型的底层实现,但是JDK9以后是不推荐使用unsafe的了,很多实现都切换到了新的VarHandle包

unsafe与varhandle

sun.misc.Unsafejava.lang.invoke.VarHandle 都是 Java 中用于执行底层内存操作和原子操作的机制。它们的主要目标都是为库开发者(如 java.util.concurrent 包的实现者)提供构建高性能、无锁数据结构的基础能力

相比于unsafe,varhandle的安全性更高,例如不能突破java的一些语法限制(final不再可以被修改),同时提供更多CAS操作

volatile

volatile也是字节码层面的并发控制手段,其能力主要包括:

  • 可见性保证:通过字节码增加的写回操作,要求CPU写缓存的操作必须同步刷新内存,并通过总线广播给其他线程,标记为已修改状态,在其他线程使用其值之前先从内存中重新刷新该值

  • 有序性保证:通过增加内存屏障,避免指令重排序

hashCode()与equals()的区别与联系

hashCode是语法约束上的相等,equals是业务上的相等

hashCode方法是HashSet、HashMap等集合计算哈希散列的方法,当两个对象hashCode结果相等,意味着这两个对象在HashSet中是冲突的,即使这两个对象可能并不是一个

而equals常常被用于重写逻辑并进行业务相等的比较,当我们重写了equals但不重写hashCode,有可能出现业务相等但是计算哈希散列不等的情况,导致使用HashMap或HashSet存储并判断isExist时出现问题

0

评论区