java悲观锁乐观锁
【摘要】 悲观锁?悲观锁总是假设最坏的情况,认为总是会存在多个线程会同时修改数据,所以每次在获取资源操作的时都会进行上锁,在同一时间内,只允许一个线程使用,用完后释放资源。常见场景:synchronized,ReentrantLock代码示例:synchronized(this) { // 悲观锁synchronized操作}private Lock lock = new ReentrantLock...
悲观锁?
悲观锁总是假设最坏的情况,认为总是会存在多个线程会同时修改数据,所以每次在获取资源操作的时都会进行上锁,在同一时间内,只允许一个线程使用,用完后释放资源。
常见场景:synchronized,ReentrantLock
代码示例:
synchronized(this) {
// 悲观锁synchronized操作
}
private Lock lock = new ReentrantLock();
lock.lock(); // 上锁
try {
// 悲观锁lock操作
}finally{
// 释放锁
}
乐观锁?
乐观锁总是假设最好的情况,认为总是不会存在多个线程同时修改数据,所以每次在获取资源操作时,不对资源进行上锁处理,允许多个资源同时操作,不过在进行操作前,需要确认数据未被篡改,若篡改,则拉取最新值。
常见常见:CAS,AutomicInteger
代码示例:
private AtomicInteger ami = new AtomicInteger();
public void increase() {
ami.getAndIncrement();
}
private AtomicInteger ami = new AtomicInteger();
public void increase() {
ami.getAndIncrement();
}
两者的优劣:
悲观锁:使用于写场景较多的场景,可保证数据一致性。 但性能较低且可能存在线程死锁风险
乐观锁:使用于读操作较多的场景,不能完全保证数据一致性。但性能在读场景较多的场景下性能比悲观锁高,且不存在线程死锁风险。
对于乐观锁,其主要的性能损耗在自旋阶段的频繁失败和重试,但空间足够的下,可通过空间换时间进行优化,例如LongAdder。
LongAdder:空间换时间。核心原理是通过将值计算均摊,常规CAS是判断是否被更新,更新则自旋,若存在大量线程的情况,则性能就比较低了。而LongAdder则是允许多个线程进行同时进行增量操作,最后将数据所有的增量进行计算,则保证了性能上的优化, 而允许多个线程同时操作,内部是通过一个数组进行统一管理,所以空间上增大了。缺点:也提到了,这里是基于增量操作,所以直接设置值的方法肯定不行,所以应用的场景有一定的限制
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)