All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.katool.redis.util.lock.LockMessageWatchDog Maven / Gradle / Ivy

The newest version!
package cn.katool.redis.util.lock;
import cn.hutool.core.util.ObjectUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.DependsOn;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.LockSupport;
@Component
@Slf4j
public class LockMessageWatchDog implements MessageListener {
    // todo: 后期优化为redis-zset
    public static volatile ConcurrentHashMap> threadWaitQueue=new ConcurrentHashMap<>();;
    public static final String LOCK_MQ_NAME = "LOCK:RELASE:QUEUE";
    @SneakyThrows
    @Override
    public void onMessage(Message message, byte[] pattern) {
      log.debug("从消息通道={}监听到消息",new String(pattern));
        log.debug("从消息通道={}监听到消息",new String(message.getChannel()));
        String lockName = new String(message.getBody()).substring(1, message.getBody().length - 1);
        log.debug("元消息={}", lockName);
        log.debug("threadWaitQueue:{}",threadWaitQueue);
        ConcurrentLinkedQueue threads = threadWaitQueue.get(lockName);
        if (ObjectUtil.isEmpty(threads)||threads.isEmpty()){
            log.debug("没有线程需要lock:{}在等待", lockName);
            threadWaitQueue.remove(lockName);
            return ;
        }
        log.debug("threads:{}",threads);
            // 从线程等待队列中获取第一个线程
            Thread peek = threads.peek();
            log.debug("唤醒线程={}",peek.getName());
//            if (peek.isInterrupted()) {
                LockSupport.unpark(peek);   // 竞争到后会自行删除
//            }
    }
    //表示监听一个频道
    @Bean
    @DependsOn({"KaTool-Init"})
    public RedisMessageListenerContainer container(RedisConnectionFactory factory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(factory);
        container.addMessageListener(this, new ChannelTopic(LOCK_MQ_NAME));
        return container;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy