面试中最常被问到的两把锁是什么?接下来就要介绍乐观锁和悲观锁了。那我们就来看看吧!锁的分类1.公平锁/非公平锁2.可重入锁3.独占锁/共享锁4.互斥锁/读写锁5.乐观锁/悲观锁6.分段锁7.偏向锁/轻量级锁/重量级lock8.自旋锁乐观锁所谓乐观其实是相对于悲观锁而言的。我们先看看百度百科里的解释。乐观锁机制采用更宽松的锁机制。大多数情况下,悲观锁是通过数据库的锁机制来实现的,以保证操作的最大程度的排他性。但随之而来的是大量的数据库性能开销,尤其是对于长事务,这样的开销往往是难以承受的。相对于悲观锁,乐观锁更倾向于开发应用。以上内容是百度百科对乐观锁的解释。如果我们要理解这把锁,就需要找一个场景来解释一下。我们以最经典的案例“老王取钱”为例。图中有三个存在,分别代表老王和老王的账号,另外一个是版本信息。默认的版本信息是1,这时候老王想买东西,发现钱不够,就去银行取钱,他果断的来到了银行。然后告诉柜员取5000元,然后柜员会从他的账户余额中扣除5000,也就是-5000。此时版本信息为1,但是我们修改金额后,需要将版本信息修改为2,因为当前保存的版本信息为1,柜员查的时候也是1。老王提款了,想改成2。然而就在这时,出事了。老王的儿媳妇出去买衣服,发现身上的钱不够,打算取点钱,于是又来到了另一家银行。这时,老王拿到了钱,但柜员还在。这是版本信息没有被修改的样子。这个时候告诉柜员取钱,柜员回去读卡发现版本信息是1。那么这个时候老王这边柜员打算记录-5000的操作进入数据库,然后将版本信息修改为2,此时验证数据库中的版本信息还是1,所以如果录入成功,将信息稳定修改为2。这时候,钱也在手上,老王高兴地拿着钱离开了。那么老王老婆这边的柜员在操作的时候就会出现问题。之前读出的账户信息版本是1,想操作的时候发现不对。有人修改了,就会出现这个。情况。但是他要修改的时候,人家现在默认是2,这时候他一对比,是1和2,然后他又想着再提交。这个时候无法完成操作,太尴尬了。情况就是证明老王老婆这边的柜员不能拿一个版本的数据覆盖老王这边的数据。这实际上相当于撤销了乐观锁。上图是乐观锁,乐观锁,多是基于数据版本(Version)记录机制。什么是数据版本?也就是给数据加上版本标识。在基于数据库表的版本方案中,一般是通过在数据库表中增加一个“版本”字段来实现的。读出数据的时候,一起读这个版本号,以后更新的时候,这个版本号加一。此时将提交数据的版本数据与数据库表中相应记录的当前版本信息进行比较。如果提交数据的版本号大于当前数据库表的版本号,则更新,否则认为是过期数据。那么什么是悲观锁呢?接下来说说什么是悲观锁。对于悲观锁约定,我们先看看百度百科里的解释。悲观锁,顾名思义,具有很强的独占和独占特性。指对数据被外界修改(包括系统当前的其他事务,以及来自外部系统的事务处理)的保守态度。因此,数据在整个数据处理过程中都是被锁定的。悲观锁的实现往往依赖于数据库提供的锁机制(只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则即使在本系统中实现了锁机制,也没有保证外部系统不会修改数据)。因为悲观锁总是假设最坏的情况,每次你去拿数据的时候,你认为别人会修改它,所以你每次拿数据的时候都会加锁,这样别人如果拿到锁就会阻塞,直到拿到锁想要获取数据。案例来袭:“工资那件小事”老王这天发工资了,工资已经到账了。然后告诉柜员,帮我看看卡里有多少钱?正在柜员验钱的时候,王太太的老婆又来取钱了。上次买的衣服不好看,又买了几件,钱不够就来银行了。这时候老王正在查钱,悲观锁就是我在读的时候,我被锁住了,你看不到。可以这样理解。此时老王老婆处于等待状态,相当于悲观锁。因为悲观锁是指当我们拿到数据的时候,不管我们打算修改不修改,悲观锁都会认为我们要修改数据,所以他就直接锁数据,其他人要操作,那你就阻塞直到轮到你获取锁了。悲观锁和乐观锁的区别就在这里。乐观锁一直认为不会有并发问题。每次取数据的时候,总以为没有其他线程会修改数据,所以不会加锁,但是更新的时候会判断之前有没有其他线程修改过数据。数据修改一般使用版本号机制或CAS操作来实现。悲观锁总是假设最坏的情况。每次取数据时,都认为其他线程会修改,所以会加锁(读锁、写锁、行锁等)。当其他线程要访问数据时,需要阻塞乐观锁和悲观锁你了解吗?
