关于乐观锁和悲观锁的概念

悲观锁

总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿 数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资
源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线 程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁
等,读锁,写锁等,都是在做操作之前先上锁。Java中 synchronized和 ReentrantLock等独占锁就是悲观锁思想的实现。

乐观锁

总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上 锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以
使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提
高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐 观锁。在Java中
java.util.concurrent.atomic包下面的原子变量类就是使用了 乐观锁的一种实现方式CAS实现的。

使用场景
乐观锁适用于写比较少的情况下(多读场景)
悲观锁适用写入比较多的场景(多写入场景)
乐观锁怎么实现

  1. 版本号机制
    一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次 数,当数据被修改时,version值会加一。当线程A要更新数据值时,在读取数 据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当 前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功
    2CAS算法
    即compare and swap(比较与交换),是一种有名的无锁算法。无锁编程, 即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的 情况下实现变量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。CAS算法涉及到三个操作数
     需要读写的内存值 V
     进行比较的值 A
     拟写入的新值 B
    当且仅当 V 的值等于 A时,CAS通过原子方式用新值B来更新V的值,否则 不会执行任何操作(比较和替换是一个原子操作)。一般情况下是一个自旋操 作,即不断的重试

乐观锁可能会存在的问题
1 乐观锁的ABA问题
2 循环时间长开销大
3 只能保证一个共享变量的原子操作

主要是面试总结的一些问题

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章