Java 高并发的三种实现案例详解
作者:java_xth 时间:2023-12-16 10:57:30
提到锁,大家肯定想到的是sychronized关键字。是用它可以解决一切并发问题,但是,对于系统吞吐量要求更高的话,我们这提供几个小技巧。帮助大家减小锁颗粒度,提高并发能力。
初级技巧-乐观锁
乐观锁使用的场景是,读不会冲突,写会冲突。同时读的频率远大于写。
悲观锁的实现:
悲观的认为所有代码执行都会有并发问题,所以将所有代码块都用sychronized锁住
乐观锁的实现:
乐观的认为在读的时候不会产生冲突为题,在写时添加锁。所以解决的应用场景是读远大于写时的场景。
中级技巧-String.intern()
乐观锁不能很好的解决大量的写冲突的问题,但是很多场景下,锁只是针对某个用户或者某个订单。 比如一个用户先创建session,才能进行后面的操作,但是由于网络的问题,创建session的请求和后续请求几乎同时到达,而并行线程可能会先处理后面的请求。一般情况需要对用户sessionMap加锁,比如上面的乐观锁。在这样的场景下,可以将锁限定在用户本身上,即原来的
这个比较类似行锁和数据库表锁的概念。显然行锁的并发能力比表锁的高很多。
实用String.intern();是这种方式的具体实现。类String维护了一个字符串池。当调用intern方法时,如果池已经包含一个等于此String对象的字符串(该对象由equals(Object)方法确定),则返回池中的字符串。可见,当String 相同时,总返回同一个对象,因此就实现了对同一用户加锁。由于所的颗粒度局限于具体用户,使得系统获得最大程度的并发。
CopyOnWriteMap?
既然说到了“类似于数据库中的行锁的概念”,就不得不提一下MVCC,Java中CopyOnWrite类实现了MVCC。Copy On Write是这样一种机制。当我们读取共享数据的时候,直接读取,不需要同步。当我们修改数据的时候,我们就把当前数据Copy一份副本,然后在这个副本 上进行修改,完成之后,再用修改后的副本,替换掉原来的数据。这种方法就叫做Copy On Write。
但是,,,JDK并没有提供CopyOnWriteMap,为什么?下面有个很好的回答,那就是已经有了ConcurrentHashMap,为什么还需要CopyOnWriteMap?
高级技巧 - 类ConcurrentHashMap
String.inter()的缺陷是类 String 维护一个字符串池是放在JVM perm区的,如果用户数特别多,导致放入字符串池的String不可控,有可能导致OOM错误或者过多的Full GC。怎么样能控制锁的个数,同时减小粒度锁呢?直接使用Java ConcurrentHashMap?或者你想加入自己更精细的控制?那么可以借鉴ConcurrentHashMap的方式,将需要加锁的对象分为多个bucket,每个bucket加一个锁,伪代码如下:
来源:https://blog.csdn.net/java_xth/article/details/81162088
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
解决mybatis 中collection嵌套collection引发的bug
Android自定义控件实现底部菜单(下)
![](https://img.aspxhome.com/file/2023/8/137478_0s.jpg)
Java 调整格式日志输出
![](https://img.aspxhome.com/file/2023/7/77957_0s.png)
Android Studio和阿里云数据库实现一个远程聊天程序
![](https://img.aspxhome.com/file/2023/4/92614_0s.jpg)
JAVA利用递归删除文件代码实例
C# Linq延迟查询的执行实例代码
Java 实战练习之网上电商项目的实现
![](https://img.aspxhome.com/file/2023/2/94192_0s.png)
Logback日志基础及自定义配置代码实例
Android客户端程序Gradle如何打包
Java使用sftp定时下载文件的示例代码
Android图片色彩变换实现方法
Kotlin类与属性及构造函数的使用详解
java 对象输入输出流读写文件的操作实例
Android 开发音频组件(Vitamio FAQ)详细介绍
Java源码解析之object类
Spring Security 图片验证码功能的实例代码
![](https://img.aspxhome.com/file/2023/0/72350_0s.jpg)
详解Java匿名内部类
![](https://img.aspxhome.com/file/2023/2/62432_0s.jpg)
Spring session 获取当前账户登录数的实例代码
Java用递归方法解决汉诺塔问题详解
![](https://img.aspxhome.com/file/2023/6/64416_0s.png)
解析Java的设计模式编程之解释器模式的运用
![](https://img.aspxhome.com/file/2023/5/63755_0s.jpg)