悲观锁和乐观锁

悲观锁 :Pessimistic Lock

乐观锁:Optimistic Lock

       这篇文章我们主要讲的是悲观锁和乐观锁的基本概念及使用场景,首先我们用一个小例子来让大家知道什么是悲观锁和乐观锁:

       小陶大学期间开始创业,是一个电商网站的创始人,小永和小攀是他电商网站中的两个线程,马上就要双十一了,为了营造一种紧张的感觉,小陶决定把某雪地靴的库存减少50,并通知小永修改,小永不敢怠慢赶紧看了一下库存,是500;与此同时,小攀接到通知把库存量减少100,小攀也赶紧看了库存,是 500;于是他们分别执行,小永把450存了进去,小攀把400存了进去,并同时把小永的数据覆盖;小陶看了一下现在的库存,发现数量不对,于是盘问了小永和小攀,想出了一个办法来解决这种冲突问题,每次读写都进行加锁操作,就是在小永操作的时候,加上一个锁,当小永操作结束的时候,小攀才能进行读写 操作;于是小陶修改了一下自己的程序,又向小永和小攀发送了同样的命令,小永进去后,加了一个锁,小攀进入block车间,等了好久发现小永还没有操作完成,直到其操作完成,小攀 才开始进行加锁操作(这就是悲观锁,每次去拿数据都认为 别人会修改,于是对每次拿到数据的时候都会加上锁,其他 线程想要拿到这个 数据就会block,直到上一个操作完成并释放锁,传统的数据库中有很多这种锁机制,比如行锁、表锁、读锁、写锁等,都是在操作之前先上锁的);一次小陶优化自家网站速度的时候发现了这个耗时的操作,苦思冥想之后决定采用第二种方案,就是小永进行操作的时候每次加上一个版本号,例如 初始化的 时候版本号为1,当小永访问并操作完成的时候,把自己最开始读取到的版本号加1,这时小攀读取到的版本号也是1,当操作完成的时候在读取数据,当版本号与自己操作前读取的一致的时候,就把版本号加 1,并储存起来,当不一致 的时候,就重新 读取操作,直至一样并保存最新的数据和版本号(这就是乐观锁,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是会在更新数据的时候根据版本号判断一下,这期间是否有人修改过数据,乐观锁适用于多读的应用 类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。);

        悲观锁和乐观锁的对比:

        两种锁各有优缺点,我们要冷静合理的进行运用,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。

参考:http://blog.csdn.net/hongchangfirst/article/details/26004335

猜你喜欢

转载自taoyongpan.iteye.com/blog/2398720