栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

分布式项目中 如何保证线程安全问题?-------Redis

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

分布式项目中 如何保证线程安全问题?-------Redis

目录

前沿:

那么我们如何解决分布式项目中 线程安全问题呢 ?

 redis 解决分布式项目中 线程安全问题

Lua脚本保证原子性:

可重入锁:

Redisson的实现分布式锁 方案

Redisson -公平锁:

Redisson -联锁:

Redisson -红锁:

 Redisson -读写锁:

 Redisson -信号量:

 Redisson -可过期性信号量:

 Redisson -闭锁:

结尾:其实在解决分布式项目中线程安全问题 不只这一种,还有其它的方案


前沿:

     在传统单体项目中,没有对项目进行集群的情况下,我们保证线程安全,可以利用到JDK(jvm)里面自带两把锁,Lock锁,Synchronized锁。保证单体项目中线程安全问题。

    在项目做了集群之后,部署到其他机器上的时候,这个时候是跨了jvm虚拟机的,JDK(jvm)自带的锁 就不能处理到其他机器上的线程

那么我们如何解决分布式项目中 线程安全问题呢 ?

      基于上面的问题 这个时候我们可以把 锁整成为一个公共的服务或者中间件。线程需要拿到锁之后才可以执行相应的服务。 这样就可以保证线程安全性

 redis 解决分布式项目中 线程安全问题

    思路:在解决分布式事务中 可以用redis实现 ,因为redis在设置值和获取值是单线程的 ,单线程天然就不会有线程安全问题,可以先把锁存到redis里面。如果一个线程能从redis里面拿到锁,那就可以去访问对应的服务。。redis在进行数据持久化这些,是多线程的。

     具体实现:假设现在有三个线程 A B C ,这三个线程属于不同的机器上。我们把三个线程的key都假设一样,value值为锁,此时三个线程都是进来,由于redis的key是唯一的,那么此时只会有一个线程把锁存入成功,假设现在是A存入锁成功了,那么A现在可以去执行对应的服务。A执行完了后,把key删除掉。其他线程又开始存,假设现在是B线程把锁存入了,刚刚执行到中途,这时候Redis宕机了,会导致其他线程使用相同key存入不成功,一直执行不到业务代码,照成死锁。(并非这一种情况,还有其他概率,误删其他线程的key等)

Lua脚本保证原子性:

  基于上面的说的,也产生了很多不可避免的概率问题:误删其他线程的key,死锁产生。

基于误删情况,这时候 Lua脚本可以保证原子性  判断是不是自己的锁(UUID)和删除锁是一组操作 。



可重入锁:

上面的情况,还有极端情况,就是获取锁的时候没有成功,也就还没有进入到if判断里面,线程想当就是白跑一趟,这是时候,就会可以使用 到可重入锁,简单理解就是一个线程在进来的时候是失败了,这时候让这个线程等待片刻之后再次尝试获取锁

Redisson的实现分布式锁 方案

基于上面的情况,redis实现的分布式锁,我们开发人员考虑的细节是比较多的,这时候有一款 Redisson的工具,完美帮我们解决了这些细节问题,其实就是对redis的封装

 用法:导入对应依赖,Redisson链接到redis,链接成功就可以使用Redisson里面的api操作redis了

 Redisson里面提供了一个线程,作用类似看门狗,当业务代码执行完成后,会根据默认的时间删除,如果在默认时间没有执行,会加长时间。如果有设置过期时间,直接把设定的过期时间作为锁的过期时间,然后使用Lua脚本获取锁,没获取到锁的线程会while自旋重入不停地尝试获取锁

Redisson -公平锁:

  它保证了当多个Redisson客户端线程同时请求加锁时,优先分配给先发出请求的线程。

Redisson -联锁:

    顾名思义联合一起锁 。才算成功  类似于王者荣耀里,大家都点击确认才可以选英雄。

Redisson -
红锁:

    大部分节点上加锁成功才算成功,如果没有获取到成功,则把部分已锁的释放掉。

 Redisson -读写锁:

顾名思义读锁和写锁。如果如果是读锁,一个在读,其他人也是可以读的。但是有一个人在写,其他人必须要等这个人写完,才能去写。简单理解就是我在写数据的时候,你是不能来读的。

 Redisson -信号量:

简单理解就是一Reids里面保存的一个数字,可以实现原子性的加减

操作:获取到信号量对象,把数字存入 信号量里面取个名字,后面通过名字取。就算很多个线程来,也只会一个线程完整操作成功。 秒杀的商品可以数量,可以放到信号量实现

 Redisson -可过期性信号量:

 就是在信号量的基础上,设置一个过期时间

 Redisson -闭锁:

闭锁可以实现多个线程都执行完才是完成的效果,否则闭锁会等待。理解:打排位的时候,正常情况下,都是大家加载到100后之后,才一起进入到游戏里面。

结尾:其实在解决分布式项目中线程安全问题 不只这一种,还有其它的方案

例如本地消息表,zookeeper 等。下一篇会写关于目前最流行的分布式解决方案--zookeeper



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/462102.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号