乐观锁与悲观锁
乐观锁
总是假设最好的情况,每次去数据库拿数据都认为其他线程不会修改,所以不会上锁,但是在更新的时候会判断一下有没有线程对数据进行过修改,可以使用版本号和CAS算法实现。 应用
乐观锁适用于多读取的应用场景,这样可以提高吞吐量。 实现方式
一般是在数据表中加上一个数据版本号version字段,记录数据被修改的次数,当数据被修改时,version加1。
线程A要更新数据值的时候,读取数据的同时也会读取version的值,在提交更新时,若读取到version的值与第一次读取的值相等,才会进行更新操作。若不等会重新操作,直到更新成功。
银行柜员需要进行存款操作
A柜员对Z账户进行存款操作
读取数据 余额为:500 version=1
同时B柜员对Z账户进行操作 扣款操作
读取数据 余额为:500 version=1
B柜员操作完
数据 余额为:400 version=2
B柜员先操作完成
A柜员提交数据,发现version=2,提交失败重新操作
即compare and swap(比较与交换),是一种有名的无锁算法。无锁编程,也就是不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量同步,所以也叫非阻塞同步。
理论:
涉及到三个操作数
1.需要读写的内存值 V
2.进行比较的值 A
3.模拟写入的新值 B
if V==A 时进行更新操作
if V!=A 重新操作
悲观锁
悲观锁总是假设最坏的情况,每次去拿数据的时候认为别的线程会进行修改,所以每次拿到数据都会进行上锁。别的线程想要读写数据就会进行阻塞,直到线程操作完成释放锁。很多关系型数据库就用到了这种锁的机制,比如行锁、表锁、读锁、写锁等都是在操作之前先上锁。 应用场景
银行
柜员A 进行存款操作
拿到数据 上锁 操作完成 释放锁 过程中 其他柜员想进行操作得等待A柜员操作完成,才可以拿到数据