吐槽

平时多积累点高并发啊锁啊缓存啊这些知识点

面试的时候可以和面试官侃侃而谈

面试官喜欢听高并发相关的

当然你能结合实际业务场景来分析

面试肯定加分

 

 

传统单点应用的线程安全问题,因为只涉及到单个应用中多线程之间的资源共享,往往通过加锁synchronized,ReentrantReadWriteLock等手段就能实现共享资源的安全;

但是现在很多大型系统,高并发的量往往较大,整个服务架构也都是设计成分布式架构,原本在单机中的共享资源转而分布在了不同的机器上,这个时候锁也应该相应的升级为分布式锁;

分布式锁有多种方式redis,zookeepper等,因为系统中本就用到了redis,就以redis为例:

分布式锁需要满足什么条件呢?

一,互斥:既然是锁,不能每个客户端都有吧,那还锁啥?

二,不能死锁:让一个客户端抱住锁,永远不释放,别的就获取不到了,那还要分布式系统干啥?

三,每个客户端的锁自己加,自己解;

redis为什么能作为分布式锁的选择呢?本身就是单进程单线程的模式,并且提供的命令具有原子性;

一般用来做分布式锁的方式有1,setnx+getset方式, 2,INCR

1,setnx+getSet方法加锁:

setnx:(set if not exists)不存在就设置,设置成功为1,已经存在,返回0;

getSet: set新key,并返回原来的value;

伪代码如下图:

redis实现并发锁 redis高并发加锁_redis实现并发锁

场景解释如下:

第一个线程读到没有锁存在,使用lock加锁,带上时间戳,超时则释放锁,防止死锁

第二个线程读到锁存在(setnx==0),进入循环,判断锁是否在超时时间内,并使用setGet方法把最新的超时时间set进去,(防止超时时间到了,多个线程读到锁超时,都去释放的情况),

第一个线程处理完业务逻辑,并删除锁,则后面的线程可以获得锁。。。

2,INCR方法加锁

这个方法会在不存在key的时候,先初始化0,然后加1,返回1;如果key存在,则在执行就会大于1;

所以使用INCR方法加锁,伪代码如下图:

redis实现并发锁 redis高并发加锁_redis实现并发锁_02

1,进行加锁操作;

2,如果锁不存在,并且加锁成功,设置过期时间;

3,如果锁已经存在,查看是否已经过了过期时间,如果过了,则重新设置。。

当然上述的分布式锁只在单机redis中安全,如果存在redis集群,可能会因为宕机,延时等问题,让锁不在唯一。需要redis官方推荐的redlock进行加锁,对此reddssion已经有良好的封装RedissionLock,建议可直接使用。

redis实现并发锁 redis高并发加锁_redis实现并发锁_03