用redis+TaskExecutor ,实时获取异步任务执行的进度

业务场景:
触发执行一个任务,前端 定时|实时 获取任务执行的进度

使用工具:
1.任务需要异步执行,使用异步任务执行器TaskExecutor
2.用Redis实时保存更新进度

代码实现:
1.用移除集合中的元素模拟业务场景,异步执行任务:每次移除一个元素

public class testTask {

    TaskExecutor taskExecutor;

    RedisService redisService;

    public void invokeTask() {
        //获取一个集合;集合中有100个元素
        List<Integer> intList = getList(100);

        //任务唯一标识
        String taskUUID = IdUtil.simpleUUID();

        //任务未开始执行,设置redis初始值 为 1等同于100%
        redisService.hset("move_list_task", taskUUID, "1");

        //异步执行移除元素
        taskExecutor.execute(() -> this.moveList(intList, taskUUID));
    }

    public List<Integer> getList(int num) {
        List<Integer> intList = Arrays.asList();
        while (num > 0) {
            intList.add(num);
        }
        return intList;
    }

   public void moveList(List<Integer> intList, String taskUUID) {
        int total = intList.size();//总计任务长度
        double unitRate = (double) (100 / total);//单次执行所占比例
        int time = 0; //执行次数初始化=0

        while (intList.size() > 0) {
            time++;

            intList.remove(intList.size() - 1);
            //更新redis
            redisService.hset("move_list_task", taskUUID, String.valueOf((time * unitRate) / total));
        }
    }
}

2.查询进度接口,根据业务需要,前端可2秒调用一次

 public String getRate(String taskUUID) {
        //获取进度-前端调用
        String rate = redisService.hget(
                "move_list_task",
                taskUUID);

        return null == rate ? "0" : rate;
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用Redis+分布式锁的情况下,通常使用Redis的单线程模型来保证分布式锁的正确性。常见的分布式锁实现方式有两种:基于Redis的SETNX命令和Redlock算法。 无论使用哪种方式,循环获取锁都是一个常见的需求。通常情况下,循环获取锁需要在一定的时间内重试获取锁,如果在规定时间内未能获取到锁,则获取锁失败。这个时间可以通过设置超时时间来实现。 下面是一个使用Redis+SETNX命令实现分布式锁的示例代码,其中包含了循环获取锁的逻辑: ``` public class RedisLock { private static final String LOCK_KEY = "lock_key"; private static final long LOCK_EXPIRE_TIME = 30000L; // 锁的过期时间,单位毫秒 private static final long RETRY_INTERVAL_TIME = 100L; // 重试获取锁的间隔时间,单位毫秒 private static final int MAX_RETRY_TIME = 10; // 最大重试次数 private RedisTemplate<String, Object> redisTemplate; public boolean lock() { int retryTime = 0; while (retryTime < MAX_RETRY_TIME) { Boolean result = redisTemplate.opsForValue().setIfAbsent(LOCK_KEY, "locked", LOCK_EXPIRE_TIME, TimeUnit.MILLISECONDS); if (result != null && result) { return true; } retryTime++; try { Thread.sleep(RETRY_INTERVAL_TIME); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } return false; } public void unlock() { redisTemplate.delete(LOCK_KEY); } } ``` 在这个例子中,我们定义了一个`RedisLock`类,使用Redis的`setIfAbsent()`命令来实现分布式锁。在`lock()`方法中,我们使用循环重试的方式获取锁。在每次循环中,我们使用`setIfAbsent()`命令尝试获取锁,如果成功获取锁则返回`true`,否则等待一段时间后继续重试。在`unlock()`方法中,我们使用Redis的`delete()`命令释放锁。 这个例子中的循环获取锁的逻辑可以根据实际需求进行调整。例如,可以根据业务需求设置重试的时间间隔、最大重试次数和锁的过期时间等参数。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值