600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > Java使用三种方法实现高并发锁的示例代码

Java使用三种方法实现高并发锁的示例代码

时间:2021-10-15 08:50:26

相关推荐

Java使用三种方法实现高并发锁的示例代码

Java|java教程

Java,实现,方法

Java-java教程

本篇文章主要介绍了java高并发锁的3种实现示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

微商通源码,vscode vue插件,ubuntu lmgrd,tomcat jsp马,可道云 sqlite,dedecms 会员插件,支持ts的前端ui框架,网络爬虫的模型图解,php 简单框架,seo基础培训引流,个人网站备案 淘客,网页的登录源代码,手机简约模板lzw

初级技巧 – 乐观锁

智能排课系统源码,vscode中熊猫安装,ubuntu win7,qps tomcat,sqlite c编译,网页设计版式规范,数据库事务实例,自搭建服务器备案,jquery图片左右轮播插件,前端常用插件和框架,爬虫能干嘛,php 搜索功能,seo反链,springboot断言,js获取第一个标签,dedecms仿下拉菜单网站,swing 嵌入网页,炫酷前端模板,cms网站后台模版,img自适应页面大小,公文管理系统 asp,微信小程序 可以用pjax吗lzw

乐观锁适合这样的场景:读不会冲突,写会冲突。同时读的频率远大于写。

c mvc 微商城源码下载,vscode怎么选中标签,替换ubuntu商标,tomcat路径怎么写,R和爬虫,在线考试系统源码 php,招远seo关键词优化,帝国网站空间后台登录,地方汽车网站模板购买lzw

以下面的代码为例,悲观锁的实现:

public Object get(Object key) { synchronized(map) { if(map.get(key) == null) {// set some values }return map.get(key); } }

乐观锁的实现:

public Object get(Object key) { Object val = null; if((val = map.get(key) == null) {// 当map取值为null时再加锁判断synchronized(map) { if(val = map.get(key) == null) { // set some value to map... }} } return map.get(key); }

中级技巧 – String.intern()

乐观锁不能很好解决大量写冲突问题,但是如果很多场景下,锁实际上只是针对某个用户或者某个订单。比如一个用户必须先创建session,才能进行后面的操作。但是由于网络原因,创建用户session的请求和后续请求几乎同时达到,而并行线程可能会先处理后续请求。一般情况,需要对用户sessionMap加锁,比如上面的乐观锁。在这种场景下,可以讲锁限定到用户本身上,即从原来的

lock.lock(); int num=storage.get(key); storage.set(key,num+1);lock.unlock();

更改为:

lock.lock(key); int num=storage.get(key); storage.set(key,num+1);lock.unlock(key);

这个比较类似于数据库表锁和行锁的概念,显然行锁的并发能力比表锁高很多。

使用String.inter()是这种思路的一种具体实现。类 String 维护一个字符串池。 当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。可见,当String相同时,String.intern()总是返回同一个对象,因此就实现了对同一用户加锁。由于锁的粒度局限于具体用户,使系统获得了最大程度的并发。

public void doSomeThing(String uid) { synchronized(uid.intern()) {// ... } }

CopyOnWriteMap?

既然说到了“类似于数据库中的行锁的概念”,就不得不提一下MVCC,Java中CopyOnWrite类实现了MVCC。Copy On Write是这样一种机制。当我们读取共享数据的时候,直接读取,不需要同步。当我们修改数据的时候,我们就把当前数据Copy一份副本,然后在这个副本 上进行修改,完成之后,再用修改后的副本,替换掉原来的数据。这种方法就叫做Copy On Write。

但是,,,JDK并没有提供CopyOnWriteMap,为什么?下面有个很好的回答,那就是已经有了ConcurrentHashMap,为什么还需要CopyOnWriteMap?

Fredrik Bromee 写道

I guess this depends on your use case, but why would you need a CopyOnWriteMap when you already have a ConcurrentHashMap?

For a plain lookup table with many readers and only one or few updates it is a good fit.

Compared to a copy on write collection:

Read concurrency:

Equal to a copy on write collection. Several readers can retrieve elements from the map concurrently in a lock-free fashion.

Write concurrency:

Better concurrency than the copy on write collections that basically serialize updates (one update at a time). Using a concurrent hash map you have a good chance of doing several updates concurrently. If your hash keys are evenly distributed.

If you do want to have the effect of a copy on write map, you can always initialize a ConcurrentHashMap with a concurrency level of 1.

高级技巧 – 类ConcurrentHashMap

String.inter()的缺陷是类 String 维护一个字符串池是放在JVM perm区的,如果用户数特别多,导致放入字符串池的String不可控,有可能导致OOM错误或者过多的Full GC。怎么样能控制锁的个数,同时减小粒度锁呢?直接使用Java ConcurrentHashMap?或者你想加入自己更精细的控制?那么可以借鉴ConcurrentHashMap的方式,将需要加锁的对象分为多个bucket,每个bucket加一个锁,伪代码如下:

Map locks = new Map(); List lockKeys = new List(); for(int number : 1 - 10000) { Object lockKey = new Object(); lockKeys.add(lockKey); locks.put(lockKey, new Object()); } public void doSomeThing(String uid) { Object lockKey = lockKeys.get(uid.hash() % lockKeys.size()); Object lock = locks.get(lockKey); synchronized(lock) { // do something } }

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。