使用Redisson的RScoredSortedSet實現延時隊列

1、實現思路

在存儲對象時,使用時間戳作爲對象的score,score最小的在set的最前面,最先取出

僞代碼如下

 RScoredSortedSet<String> set = redissonClient.getScoredSortedSet("simple");
        set.add(System.currentTimeMillis() + 10000,"1");
        set.add(System.currentTimeMillis() + 30000,"2");
        set.add(System.currentTimeMillis() + 20000,"3");

 

2、項目啓動時,啓動個線程循環獲取set中的對象,僞代碼如下

package com.ahies.stm.app.init;

import com.ahies.stm.app.centerControl.control.queueHandler.CentralControlQueueHandler;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Description
 * @Date 2019/12/9 20:30
 * @Author zsj
 */

@Component
@Order(3)
public class CentralControlQueueRunner implements CommandLineRunner {
    @Autowired
    RedissonClient redissonClient;
    public static ExecutorService queueThreadPool = Executors.newFixedThreadPool(1);
    @Autowired
    CentralControlQueueHandler controlQueueHandler;


    @Override
    public void run(String... args) throws Exception {
        queueThreadPool.execute(controlQueueHandler);

    }
}

 

2、 CentralControlQueueHandler  線程代碼如下

package com.ahies.stm.app.centerControl.control.queueHandler;

import com.ahies.stm.app.init.CentralControlQueueRunner;
import lombok.Getter;
import lombok.Setter;
import org.redisson.api.RScoredSortedSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @Description TODO
 * @Date 2019/12/9 20:32
 * @Author zsj
 */
@Getter
@Setter
@Component
public class CentralControlQueueHandler implements Runnable {
    @Autowired
    RedissonClient redissonClient;

    @Override
    public void run() {

        RScoredSortedSet<String> set = redissonClient.getScoredSortedSet("simple");
        while (true) {
            if (set.size() > 0) {
                Double score = set.firstScore().doubleValue();
                long time = System.currentTimeMillis();
                long surplus = (long) (score - time);
                if ( surplus <2000) {
                    // 提前2秒 當score 等於當前時間戳時   該對象纔可被取出
                    String first = set.first();
                    System.out.println(score);
                    System.out.println(first);
                    //取出對象
                    set.remove(first);
                }
            } else {
//當set中沒有數據時 終止循環
                break;
            }

        }

    }
}

 

3、當set中添加新的對象時,啓動線程任務,代碼如下

package com.ahies.stm.app.centerControl.control.controller;


import com.ahies.stm.app.centerControl.control.queueHandler.CentralControlQueueHandler;
import com.ahies.stm.app.constant.SysConstant;
import com.ahies.stm.app.init.CentralControlQueueRunner;
import com.ahies.stm.app.util.ResponseResult;
import io.netty.channel.Channel;
import org.redisson.api.RScoredSortedSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.net.InetSocketAddress;
import java.time.LocalDateTime;

/**
 * @Description: 
 */
@RestController
@CrossOrigin
@RequestMapping("/centerControl/control/centralControlr")
public class CentralControlrController {
  

    @Autowired
    CentralControlQueueHandler controlQueueHandler;



    @RequestMapping("/open")
    public  ResponseResult<String> open( ){
        RScoredSortedSet<String> set = redissonClient.getScoredSortedSet("simple");
        set.add(System.currentTimeMillis() + 10000,"1");
        set.add(System.currentTimeMillis() + 30000,"2");
        set.add(System.currentTimeMillis() + 20000,"3");
        //當set中添加對象時 啓動線程任務
        CentralControlQueueRunner.queueThreadPool.execute(controlQueueHandler);
        return ResponseResult.dataSuccess(null,SysConstant.QUERY_SUCCESS);
    }






}

 

發佈了231 篇原創文章 · 獲贊 46 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章