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

发布时间 - 2026-01-10 23:23:46    点击率:

假定存在这样一种情况

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

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


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 详解jQuery中的事件  Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤  Swift中swift中的switch 语句  Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】  C#如何调用原生C++ COM对象详解  西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?  头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?  香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化  Java遍历集合的三种方式  如何在云指建站中生成FTP站点?  个人摄影网站制作流程,摄影爱好者都去什么网站?  购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?  魔毅自助建站系统:模板定制与SEO优化一键生成指南  如何快速启动建站代理加盟业务?  武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?  昵图网官方站入口 昵图网素材图库官网入口  HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】  Laravel如何实现API速率限制?(Rate Limiting教程)  详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南  Laravel如何安装Breeze扩展包_Laravel用户注册登录功能快速实现【流程】  如何在云虚拟主机上快速搭建个人网站?  Python自动化办公教程_ExcelWordPDF批量处理案例  如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?  如何用IIS7快速搭建并优化网站站点?  Python正则表达式进阶教程_复杂匹配与分组替换解析  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?  javascript基于原型链的继承及call和apply函数用法分析  百度浏览器网页无法复制文字怎么办 百度浏览器复制修复  Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】  如何在腾讯云服务器上快速搭建个人网站?  Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议  Python进程池调度策略_任务分发说明【指导】  齐河建站公司:营销型网站建设与SEO优化双核驱动策略  Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】  如何快速配置高效服务器建站软件?  Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)  Laravel如何使用集合(Collections)进行数据处理_Laravel Collection常用方法与技巧  PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)  Laravel怎么使用Markdown渲染文档_Laravel将Markdown内容转HTML页面展示【实战】  php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】  Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】  Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】  Laravel怎么实现微信登录_Laravel Socialite第三方登录集成  Laravel如何配置Horizon来管理队列?(安装和使用)  Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出  高防服务器租用首荐平台,企业级优惠套餐快速部署  Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层  在centOS 7安装mysql 5.7的详细教程  微信小程序 五星评分(包括半颗星评分)实例代码  如何有效防御Web建站篡改攻击?