假定存在这样一种情况

多个用户对数据库进行写,我们的业务逻辑规定,每个用户只能写一次,大部分用户也只发一次请求。
public void write(Uers u){
// do something
}
但是有一种情况(1%的情况下吧)的就是有的用户会发两次甚至更多次写请求(因为数据库限制,我们不方便在主键上做文章)。
如果这个特殊的用户发送的两次请求时间间隔比较大,那就简单了,再每次写入的时候,写去数据库里看看,这个人有没有写过,如果已经写过了,就直接抛弃这个请求。
public void write(Uers u){
if(!checkIfExistUser(u)){
// do something
}
}
不过最大的问题就是,如果用户几乎在瞬时,发送了两个写操作。
而且假定我们的do something比较耗时,那么上面的策略就有可能失败。
为啥失败?我不用解释了吧。
那咋办?
方法一
万年不变的synchronized。
public synchronized void write(Uers u){
if(!checkIfExistUser(u)){
// do something
}
}
当然,我们得承认,有了上面的方法,就不会出现,数据库里有两条张三的记录了
但上面的锁的粒度太大了,张三写的时候,李四也不能写了。
其实我们想要的只是:张三自己本人,不能同时多次写入。
方法二
类 String 维护一个字符串池。 当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。可见,当String相同时,String.intern()总是返回同一个对象,因此就实现了对同一用户加锁。由于锁的粒度局限于具体用户,使系统获得了最大程度的并发。
public synchronized void write(Uers u){
synchronized(u.getUserId.intern()) {
// do something
}
}
上面的思路就保证了张三写的时候,李四可以写,但是不能两个张三一块写。
方法三
其实我个人觉得,方法二已经很好了,如果非要说方法二还有什么问题的话,只能说:
String.inter()的缺陷是类 String 维护一个字符串池是放在JVM perm区的,如果用户数特别多,导致放入字符串池的String不可控,有可能导致OOM错误或者过多的Full GC。
那咋办?
public synchronized void write(Uers u){
String userSuffix=getSuffix(u);
synchronized(userSuffix.intern()) {
// do something
}
}
至于那个获得后缀的策略,大家自己想。
有了这个策略,我就能保证1亿个用户,可能只有10000个不同的后缀。
有可能张三李四的后缀一样,但是张三李四同时发请求的概率,应该也不会太大。就算真的同时发了,那你等一下不行么?
方法四
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
}
}
个人感觉和方法三的核心差不多。
方法五
如果是集群情况下,两个张三几乎瞬时进入两台服务器,那java语言级别的锁都得报废。
可以使用redis的分布式锁
方法六
使用zookeeper
只是听说有这么一个思路,但是本人没用过zookeeper,这个方法就不多说了。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
# java
# 高并发
# 数据库锁
# 数据库高并发写入
# java数据库并发处理
# 深入了解java NIO之Selector(选择器)
# Java NIO Selector用法详解【含多人聊天室实例】
# JAVA代码设置selector不同状态下的背景颜色
# java的多线程高并发详解
# 详解java解决分布式环境中高并发环境下数据插入重复问题
# java web在高并发和分布式下实现订单号生成唯一的解决方案
# java高并发锁的3种实现示例代码
# java web如何解决瞬间高并发
# Java 高并发九:锁的优化和注意事项详解
# Java进阶之高并发核心Selector详解
# 李四
# 有可能
# 两次
# 咋办
# 库里
# 很好
# 放在
# 过了
# 那就
# 就能
# 多个
# 就有
# 说了
# 不多
# 那你
# 太大
# 写了
# 两条
# 发了
# 可以使用
相关文章:
如何快速搭建高效WAP手机网站吸引移动用户?
如何挑选优质建站一级代理提升网站排名?
重庆市网站制作公司,重庆招聘网站哪个好?
c# 在ASP.NET Core中管理和取消后台任务
如何打造高效商业网站?建站目的决定转化率
建站之星后台管理系统如何操作?
如何零基础开发自助建站系统?完整教程解析
Android滚轮选择时间控件使用详解
网站制作公司广州有几家,广州尚艺美发学校网站是多少?
网站制作新手教程,新手建设一个网站需要注意些什么?
nginx修改上传文件大小限制的方法
独立制作一个网站多少钱,建立网站需要花多少钱?
如何快速搭建个人网站并优化SEO?
广州营销型建站服务商推荐:技术优势与SEO优化解析
佛山企业网站制作公司有哪些,沟通100网上服务官网?
天津个人网站制作公司,天津网约车驾驶员从业资格证官网?
如何确保FTP站点访问权限与数据传输安全?
如何在云主机上快速搭建多站点网站?
如何用y主机助手快速搭建网站?
制作宣传网站的软件,小红书可以宣传网站吗?
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
,想在网上投简历,哪几个网站比较好?
如何在Windows服务器上快速搭建网站?
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
婚礼视频制作网站,学习*后期制作的网站有哪些?
云南网站制作公司有哪些,云南最好的招聘网站是哪个?
如何在云指建站中生成FTP站点?
建站之星如何快速生成多端适配网站?
建站主机选购指南:核心配置与性价比推荐解析
简易网站制作视频教程,使用记事本编写一个简单的网页html文件?
武汉外贸网站制作公司,现在武汉外贸前景怎么样啊?
定制建站方案优化指南:企业官网开发与建站费用解析
无锡制作网站公司有哪些,无锡优八网络科技有限公司介绍?
如何在西部数码注册域名并快速搭建网站?
阿里云高弹*务器配置方案|支持分布式架构与多节点部署
如何访问已购建站主机并解决登录问题?
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
企业网站制作费用多少,企业网站空间一般需要多大,费用是多少?
美食网站链接制作教程视频,哪个教做美食的网站比较专业点?
建站之星代理如何获取技术支持?
,巨量百应是干嘛的?
c# await 一个已经完成的Task会发生什么
如何高效搭建专业期货交易平台网站?
如何通过虚拟主机空间快速建站?
制作网站公司那家好,网络公司是做什么的?
建站之星上传入口如何快速找到?
如何制作算命网站,怎么注册算命网站?
行程制作网站有哪些,第三方机票电子行程单怎么开?
设计网站制作公司有哪些,制作网页教程?
企业宣传片制作网站有哪些,传媒公司怎么找企业宣传片项目?
*请认真填写需求信息,我们会在24小时内与您取得联系。