『Java』面试官:如何实现一个乐观锁(小白都能看得懂的代码)( 二 )
本文插图
这里我们可以看到自增操作主要是使用了unsafe的getAndAddInt方法 。 因为不是专门介绍AtomicInteger , 所以不会对源码进行相信的分析 。
(1)Unsafe:Unsafe是位于sun.misc包下的一个类 , Unsafe类使Java语言拥有了类似C语言指针一样操作内存空间的能力 。 也就是说我们直接操作了内存空间进行了加1操作 。
(2) unsafe.getAndAddInt:其内部又调用了Unsafe.compareAndSwapInt方法 。 这个机制叫做CAS机制 ,
CAS 即比较并替换 , 实现并发算法时常用到的一种技术 。 CAS操作包含三个操作数——内存位置、预期原值及新值 。 执行CAS操作的时候 , 将内存位置的值与预期原值比较 , 如果相匹配 , 那么处理器会自动将该位置值更新为新值 , 否则 , 处理器不做任何操作 。
我们使用一个例子来解释相信你会更加的清楚 。
比如说给你儿子订婚 。 你儿子就是内存位置 , 你原本以为你儿子是和杨贵妃在一起了 , 结果在订婚的时候发现儿子身边是西施 。 这时候该怎么办呢?你一气之下不做任何操作 。 如果儿子身边是你预想的杨贵妃 , 你一看很开心就给他们订婚了 , 也叫作执行操作 。 现在你应该明白了吧 。
但是这样的CAS机制会带来一个比较常见的问题 。 那就是ABA问题 , 举个例子 , 你看到桌子上有100块钱 , 然后你去干其他事了 , 回来之后看到桌子上依然是100块钱 , 你就认为这100块没人动过 , 其实在你走的那段时间 , 别人已经拿走了100块 , 后来又还回来了 。 这就是ABA问题 。
本文插图
那这时候又该如何解决ABA问题呢?既然有人动了 , 那我们对数据加一个版本控制字段 , 只要有人动过这个数据 , 就把版本进行增加 , 我们看到桌子上有100块钱版本是1 , 回来后发现桌子上100没变 , 但是版本却是2 , 就立马明白100块有人动过 。
5、乐观锁思想
OK , 上面说了这么多 , 其实就是想说一句话那就是乐观锁可以由CAS机制+版本机制来实现 。
乐观锁假设认为数据一般情况下不会产生并发冲突 , 所以在数据进行提交更新的时候 , 才会正式对数据是否产生并发冲突进行检测 , 如果发现并发冲突了 , 则让返回用户错误的信息 , 让用户决定如何去做 。
(1)CAS机制:当多个线程尝试使用CAS同时更新同一个变量时 , 只有其中一个线程能更新变量的值 , 而其它线程都失败 。 CAS 有效地说明了“ 我认为位置 V 应该包含值 A;如果包含该值 , 则将 B 放到这个位置;否则 , 不要更改该位置 , 只告诉我这个位置现在的值即可“ 。
(2)版本机制:CAS机制保证了在更新数据的时候没有被修改为其他数据的同步机制 , 版本机制就保证了没有被修改过的同步机制(意思是上面的ABA问题) 。
基于这个思想我们就可以实现一个乐观锁 。 下面我们写一下代码 。 这个代码在我自己电脑上亲测通过 。
二、实现一个乐观锁第一步:定义我们要操作的数据
本文插图
第二步:定义一个乐观锁
本文插图
第三步:测试
本文插图
定义了两个线程 , 然后进行读写操作
第四步:输出结果
本文插图
这个结果可以看到在读数据的时候只要发现没有变化即可 , 但是更新数据的时候要判断当前的版本号和预期的版本号是否一致 , 如果一致那就更新 , 如果不一致 , 那就说明更新失败 。
- 海峡生活汇印度对中国虎视眈眈,我国将如何迎接挑战,英国仍想着事后清算
- JEECG前端Chrome调试小技巧汇总
- 购房置业▲社保未缴满15年如何补救,这4种方式都可以,劝你不要选第4个
- 崔元新不输当前5G新机的4款旧旗舰,你如何选择呢?,新一轮降价潮
- 讲故事的女人是如何对待她们的?说出来你绝对不敢相信,萨达姆俘虏美国女兵后
- 我家的猫叫皮蛋台积电急了,纯国产芯片来了,华为设计,中芯生产你如何评价?,ASML断供失效
- 聚成教育Excel表格技巧—Excel 如何给文字加拼音
- 聚成教育PPT演示技巧—如何快速将 PPT 的字体统一为微软雅黑
- 海峡两岸@海峡两岸丨台湾民众申请纾困金,如何证明自己穷成了一大难题
- 科技第一帅2020年游戏本该如何买?懂行的都会选择这三款