全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

java高并发写入用户信息到数据库的几种方法

假定存在这样一种情况

多个用户对数据库进行写,我们的业务逻辑规定,每个用户只能写一次,大部分用户也只发一次请求。

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详解  # 李四  # 有可能  # 两次  # 咋办  # 库里  # 很好  # 放在  # 过了  # 那就  # 就能  # 多个  # 就有  # 说了  # 不多  # 那你  # 太大  # 写了  # 两条  # 发了  # 可以使用 


相关文章: 如何挑选最适合建站的高性能VPS主机?  如何在IIS服务器上快速部署高效网站?  MySQL查询结果复制到新表的方法(更新、插入)  如何解决VPS建站LNMP环境配置常见问题?  网站制作外包价格怎么算,招聘网站上写的“外包”是什么意思?  如何在阿里云通过域名搭建网站?  如何通过cPanel快速搭建网站?  建站168自助建站系统:快速模板定制与SEO优化指南  建站10G流量真的够用吗?如何应对访问高峰?  如何高效利用亚马逊云主机搭建企业网站?  南京做网站制作公司,南京哈发网络有限公司,公司怎么样,做网页美工DIV+CSS待遇怎么样?  如何选择美橙互联多站合一建站方案?  建站主机是否属于云主机类型?  高端建站如何打造兼具美学与转化的品牌官网?  微信h5制作网站有哪些,免费微信H5页面制作工具?  建站org新手必看:2024最新搭建流程与模板选择技巧  免费公司网站制作软件,如何申请免费主页空间做自己的网站?  建站IDE高效指南:快速搭建+SEO优化+自适应模板全解析  寿县云建站:智能SEO优化与多行业模板快速上线指南  如何制作算命网站,怎么注册算命网站?  韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南  c# 在ASP.NET Core中管理和取消后台任务  ,怎么用自己头像做动态表情包?  Bpmn 2.0的XML文件怎么画流程图  网站制作公司广州有几家,广州尚艺美发学校网站是多少?  ,sp开头的版面叫什么?  网站制作话术技巧,网站推广做的好怎么话术?  香港服务器部署网站为何提示未备案?  如何用wdcp快速搭建高效网站?  网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?  宝塔建站后网页无法访问如何解决?  利用JavaScript实现拖拽改变元素大小  rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted  济南网站制作的价格,历城一职专官方网站?  香港服务器租用费用高吗?如何避免常见误区?  建站之星在线版空间:自助建站+智能模板一键生成方案  微信小程序 五星评分(包括半颗星评分)实例代码  成都网站制作报价公司,成都工业用气开户费用?  如何通过FTP空间快速搭建安全高效网站?  如何在宝塔面板创建新站点?  简历在线制作网站免费,免费下载个人简历的网站是哪些?  浙江网站制作公司有哪些,浙江栢塑信息技术有限公司定制网站做的怎么样?  网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?  简易网站制作视频教程,使用记事本编写一个简单的网页html文件?  ,想在网上投简历,哪几个网站比较好?  制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?  Python lxml的etree和ElementTree有什么区别  linux top下的 minerd 木马清除方法  教程网站设计制作软件,怎么创建自己的一个网站?  建站之星展会模板:智能建站与自助搭建高效解决方案 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。