Redis如何实现分布式阻塞队列?

1. Redis分布式锁实现原理

分布式锁本质上要实现的目标就是在Redis里面占一个“茅坑”,当别的进程也要来占时,发现已经有人蹲在那里了,就只好放弃或者稍后再试。占坑一般是使用setnx(set if not exists)指令,只允许被一个客户端占坑。先来先占,用完了,再调用del指令释放茅坑。

死锁问题:如果逻辑执行到中间出现异常了,可能会导致del指令没有被调用,这样就会陷入死锁,锁永远得不到释放,解决这个问题我们在拿到锁之后,再给锁加上一个过期时间,比如 5s,这样即使中间出现异常也可以保证 5 秒之后锁会自动释放。

2. 普通非阻塞锁实现
在这里插入图片描述
2.1 存在问题

如果某一个进程没有拿到锁得到了false的结果那么次进程是否执行当前任务?显然对于一般情况来说我们的任务都是必须执行的那么此时我们就要考虑该何时执行了,在传统的锁中我们如果没有拿到锁线程就进入了阻塞状态那么此处我们是否可以改进同样实现阻塞唤醒机制。

3. 分布式阻塞锁具体实现

3.1 解决思路

(1)首先我们改造lock锁,当不能创建key时就利用当前key阻塞当前线程

(2)当某一个线程释放锁时通过redis的pub/sub发送一个消息消息内容为key

(3)所有使用锁的应用监听lock通道的消息,在收到消息时通过key唤醒对应线程

3.2具体实现

package com.hgy.common.redis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

import java.util.HashMap;

public class RedisLock extends JedisPubSub {
   
	//是否已经初始化监听
	private static volatile boolean isListen = false;

	//每一个redis的key对应一个阻塞对象
	private HashMap blockers = new HashMap<>();

	private Jedis jedis;

	//当前获得锁的线程
	private Thread curThread;

	public RedisLock(Jedis jedis) {
   
		this.jedis = jedis;
		//保证没一个应用只初始化一次监听
		if (!isListen) {
   
			synchronized (RedisLock.class) {
   
				if (!isListen) {
   
					// 启动一个线程做消息监听
					new Thread
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值