网站首页 > 精选教程 正文
在Java并发场景中,会涉及到各种各样的锁,比如:分段锁、公平锁,独享锁、共享锁、乐观锁,悲观锁等等,感觉特别的繁杂,一句话很难描述清楚,但又特别的重要。
下面我就通过图文并茂的方式,一起来梳理和详解最全锁!
——嘀嘀!上车了!准备上车了!!——
乐观锁 VS 悲观锁
乐观锁与悲观锁是一种广义上的概念,在Java并发编程和数据库中都有实际的应用场景。
1.乐观锁
顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制来实现。
比如典型的应用就是Java并发里的CAS实现,Java并发包中的很多类都使用了CAS技术,是实现乐观锁的核心操作。
CAS全称 Compare And Swap(比较与交换),是一种无锁算法。
简单来说,CAS算法有3个三个操作数:
- 需要读写的内存值 V
- 进行比较的值 A
- 要写入的新值 B
当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则返回V。
这是一种乐观锁的思路,它相信在它修改之前,没有其它线程去修改它。
2.悲观锁
而悲观锁恰恰相反,它认为在它修改之前,一定会有其它线程去修改它,所以每次在拿数据的时候都会上锁。
典型代表就是一篇我谈到的Synchronized的底层实现原理,就是典型的悲观锁。
公平锁 VS 非公平锁
1.公平锁
就是很公平,在并发环境中,每个线程在获取锁时会先查看此锁维护的等待队列,如果为空,或者当前线程是等待队列的第一个,就占有锁,否则就会加入到等待队列中,以后会按照FIFO的规则从队列中取到自己。
公平锁的应用
java jdk并发包中的ReentrantLock可以指定构造函数的boolean类型来创建公平锁,比如:公平锁可以使用new ReentrantLock(true)实现。
2.非公平锁
非公平锁上来就直接尝试占有锁,如果尝试失败,就再采用类似公平锁那种方式。
非公平锁的优点是可以减少唤起线程的开销,整体的吞吐效率高,因为线程有几率不阻塞直接获得锁,CPU不必唤醒所有线程,缺点是处于等待队列中的线程可能会饿死,或者等很久才会获得锁。
非公平锁的应用
java jdk并发包中的ReentrantLock的构造函数的默认就是采用非公平锁的实现,使用new ReentrantLock(false)来实现,与上面的公平锁相反的声明方式。
独享锁 VS 共享锁
1.独享锁
是指该锁一次只能被一个线程所持有,比如:刚刚谈到的ReentrantLock就是独享锁。
2.共享锁
是指该锁可被多个线程所持有,Lock的另一个实现类ReadWriteLock,其读锁就是共享锁,其写锁却是独享锁。
ReadWriteLock的读锁(共享锁)可保证并发读是非常高效,但读写,写读 ,写写的过程是互斥的。
这样设计的原因是:就是尽最大的解放并发读的操作,因为读占据了更大的访问请求,我只会在涉及少部分写的操作的时候,才考虑独享锁,从而提升并发的效率。
这样的设计理念,其本质就是要读写分离,也许你也会想到数据库的读写分离机制。
技术有意思的地方就是在于,很多技术方案虽然实现不一样,但是背后的设计理念往往都是相同的,完全可以互相借鉴与融会贯通。
分段锁
分段锁也是一种锁的设计,比如:JDK 1.7版本里的ConcurrentHashMap就是通过分段锁的形式来实现高效的并发操作。
ConcurrentHashMap中的分段锁称为Segment,当需要put元素的时候,并不是对整个hashmap进行加锁,而是先通过hashcode来知道他要放在哪一个分段中,然后对这个分段进行加锁。
所以当多线程put的时候,只要不是放在一个分段中,就实现了真正的并行的插入。
分段锁这样设计的目的其本质就是细化锁的粒度,从而提升并发的效率!
以上就是最全锁的梳理和总结!
- 上一篇: 程序员:我终于知道Java这些“锁”事了
- 下一篇: mysql的锁机制
猜你喜欢
- 2024-11-21 Java中的重重“锁”事
- 2024-11-21 线程进阶:多任务处理——Java中的锁(Unsafe基础)
- 2024-11-21 深入理解MySQL锁机制原理
- 2024-11-21 Java并发锁的原理,你所不知道的Java“锁”事
- 2024-11-21 阿里二面:你知道Java中的同步与锁机制详解?
- 2024-11-21 知识点深度解读系列-JAVA锁
- 2024-11-21 图解Java中的锁:什么是死锁?怎么排查死锁?怎么避免死锁?
- 2024-11-21 Java锁与线程的那些“不可描述”的事儿
- 2024-11-21 让人闻风丧胆的 Mysql 锁机制
- 2024-11-21 Java中各种锁的理解
你 发表评论:
欢迎- 04-11Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- 04-11Java中你知道几种从字符串中找指定的字符的数量
- 04-11探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- 04-11Python字符串详解与示例(python字符串的常见操作)
- 04-11java正则-取出指定字符串之间的内容
- 04-11String s1 = new String("abc");这句话创建了几个字符串对象?
- 04-11java判断字符串中是否包含某个字符
- 04-11关于java开发中正确的发牌逻辑编写规范
- 最近发表
-
- Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- Java中你知道几种从字符串中找指定的字符的数量
- 探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- Python字符串详解与示例(python字符串的常见操作)
- java正则-取出指定字符串之间的内容
- String s1 = new String("abc");这句话创建了几个字符串对象?
- java判断字符串中是否包含某个字符
- 关于java开发中正确的发牌逻辑编写规范
- windows、linux如何后台运行jar(并且显示进程名)
- 腾讯大佬私人收藏,GitHub上最受欢迎的100个JAVA库,值得学习
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)