Java多线程 乐观锁、悲观锁、以及CSA算法

Java多线程 乐观锁、悲观锁、以及CAS算法

1、乐观锁

1.1 概念

该锁总是很乐观的,在多线程并发过程中,不会认为别人每次会修改自己的数据,所以在别人操作时候不会上锁,如果是读取数据,那么直接返回数据,如果是更新数据,那么做一次判断,是否有别人更新,等待别人更新后再更新。那么这个很明显的优势就是,性能较高,不会因为每次上锁而降低性能,应用于高吞吐的操作。可以使用版本号机制和CAS算法实现

1.2 应用

(1)适用场景
比较适合读取操作比较频繁的场景,如果出现大量的写入操作,数据发生冲突的可能性就会增大,为了保证数据的一致性,应用层需要不断的重新获取数据,这样会增加大量的查询操作,降低了系统的吞吐量。

(2)jdk中的应用
在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS(compare and set)实现的。
例如:
AtomicBoolean(用原子方式更新的boolean值)

AtomicInteger(用原子方式更新的int值)

AtomicLong(用原子方式更新的long值)

简单实例

class Count{

    // 共享变量(使用AtomicInteger来替代Synchronized锁)

    private AtomicInteger count = new AtomicInteger(0);

    public Integer getCount() {

        return count.get();

    }

    public void increase() {

        count.incrementAndGet();

    }

}

1.3 乐观锁的缺点

(1)只能保证一个共享变量的原子操作
CAS 只对单个共享变量有效,当操作涉及跨多个共享变量时 CAS 无效。但是从 JDK 1.5开始,提供了AtomicReference类来保证引用对象之间的原子性,你可以把多个变量放在一个对象里来进行 CAS 操作.所以我们可以使用锁或者利用AtomicReference类把多个共享变量合并成一个共享变量来操作。

(2)ABA 问题
如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然是A值,那我们就能说明它的值没有被其他线程修改过了吗?很明显是不能的,因为在这段时间它的值可能被改为其他值,然后又改回A,那CAS操作就会误认为它从来没有被修改过。这个问题被称为CAS操作的 "ABA"问题。

JDK 1.5 以后的 AtomicStampedReference 类就提供了此种能力,其中的 compareAndSet 方法就是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。

(3)循环时间长开销大
自旋CAS(也就是不成功就一直循环执行直到成功)如果长时间不成功,会给CPU带来非常大的执行开销。

2 、悲观锁

2.1 概念

该类锁总是很悲观的,在多线程并发过程中,总是认为别人会侵犯自己,比如别人来读取或者修改数据,都会先上锁,当处理完成后再释放锁。如果是写,倒是还好,如果只是读取呢?那么势必会减低读取性能。这种锁独自占用资源,也叫做独占锁

2.2 应用

(1)适用的应用场景
比较适合写入操作比较频繁的场景,如果出现大量的读取操作,每次读取的时候都会进行加锁,这样会增加大量的锁的开销,降低了系统的吞吐量。

(2)jdk中的应用

Java中synchronized和ReentrantLock等独占锁

3、CAS算法

3.1 CAS 算法原理

(1)CAS有3个操作数,内存值V旧的预期值E要修改的新值N。当且仅当预期值E和内存值V相同时,将内存值V修改为N,否则什么都不做。但一般情况下是一个自旋操作,即不断的重试。
(2)过程大概如下图:
在这里插入图片描述

3.2 CAS与synchronized的使用情景

(1)CAS适用于写比较少的情况下(多读场景,冲突一般较少)
对于资源竞争较少(线程冲突较轻)的情况,使用synchronized同步锁进行线程阻塞和唤醒切换以及用户态内核态间的切换操作额外浪费消耗cpu资源;而CAS基于硬件实现,不需要进入内核,不需要切换线程,操作自旋几率较少,因此可以获得更高的性能。

(2)synchronized适用于写比较多的情况下(多写场景,冲突一般较多)。
对于资源竞争严重(线程冲突严重)的情况,CAS自旋的概率会比较大,从而浪费更多的CPU资源,效率低于synchronized

发布了27 篇原创文章 · 获赞 17 · 访问量 2190

猜你喜欢

转载自blog.csdn.net/qqq3117004957/article/details/104580098
今日推荐