跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 异步任务问题
未分類
4 2 月 2021

异步任务问题

异步任务问题

資深大佬 : qm332207252 7

一个接口,接收到一次请求,调用 service 执行异步任务,异步任务执行中,直接返回响应,再次请求该接口或者其他用户请求该接口(更或者是自动任务执行),调用 service,上次请求这个任务还在执行中,因此返回处理中,这种 java 后台有比较好的实现吗?

大佬有話說 (15)

  • 資深大佬 : dqzcwxb

    加个锁

  • 資深大佬 : stonewu

    最简单的方式就是定义一个全局变量

  • 主 資深大佬 : qm332207252

    @dqzcwxb 能详细点说明下不

  • 資深大佬 : zoharSoul

    记到任务表.

  • 主 資深大佬 : qm332207252

    @stonewu 我也想过在调用异步方法外面用个什么变量标记执行状态

  • 資深大佬 : MicroGalaxy

    这种需求还是全局变量最简单好用

  • 主 資深大佬 : qm332207252

    @MicroGalaxy 类似前端做登录按钮,请求表格数据什么的异步请求加状态标记那样咯?

  • 資深大佬 : killergun

    Ticket ?根据 Ticket 来获取进展

  • 資深大佬 : guoyuchuan

    异步任务可以配置线程池,这样就不会存在你说的这个问题了

  • 資深大佬 : guoyuchuan

    @guoyuchuan #9 不对,说错了

  • 資深大佬 : liian2019

    单机就整个 AtomicBoolean,分布式就整个 redis 记一下

  • 資深大佬 : RedBeanIce

    java 异步任务有很多方法,CompletableFuture.runAsync

    至于第二次进来的问题,加个锁就行,上有说明,单机和分布式

  • 資深大佬 : oneisall8955

    单机还是集群,单机配只静态变量,集群搞 redis,加个 key 标识

  • 資深大佬 : siweipancc

    占坑#

  • 資深大佬 : siweipancc

    @Log
    @RestController
    @SpringBootApplication
    public class WebApplication {

    public static void main(String[] args) {
    SpringApplication.run(WebApplication.class, args);
    }

    static final String CREATED = “create”;
    static final String PROCESS = “process”;
    static final String COMPLETE = “complete”;

    @PostMapping(“generate”)
    public ResponseEntity<Response> generate(@RequestBody Request request) {
    return ResponseEntity.ok(generate(request.input, request.taskId));
    }

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private ThreadPoolTaskExecutor executor;

    @PostConstruct
    public void init() {
    redisTemplate.setKeySerializer(RedisSerializer.string());
    redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
    }

    Function<UUID, String> valKeyFunc = uuid -> “value::” + uuid;
    Duration expire = Duration.ofMinutes(30L);

    public Response generate(Integer input, UUID taskId) {

    if (taskId == null) {
    check(input != null, “请输入值”);
    UUID uuid = createTask(input);
    return new Response(CREATED, null, uuid, expire.getSeconds());
    }

    String key = valKeyFunc.apply(taskId);
    Long expire = redisTemplate.getExpire(key);
    Entity value;
    try {
    value = (Entity) redisTemplate.opsForValue().get(key);
    } catch (ClassCastException e) {
    log.warning(e.getMessage());
    e.printStackTrace();
    throw new RuntimeException(“服务器内部错误”);
    }
    check(value != null, “任务 ” + taskId + ” 不存在或者已经过期”);
    assert value != null;
    check(value.complete != null, “服务器内部错误”);
    if (!value.complete) {
    return new Response(PROCESS, null, taskId, expire);
    }

    return new Response(COMPLETE, value, taskId, expire);
    }

    private static void check(Boolean condition, String msg) {
    if (!Boolean.TRUE.equals(condition)) {
    throw new RuntimeException(msg);
    }
    }

    private UUID createTask(Integer input) {
    UUID uuid = UUID.randomUUID();
    executor.execute(() -> {
    try {
    Entity entity = new Entity(uuid, false, new Date(), null, input, null);
    log.info(String.format(“begin task: %s, input: %s”, uuid, input));
    String key = valKeyFunc.apply(uuid);
    redisTemplate.opsForValue().set(key, entity, expire);
    log.info(String.format(“set task: %s, input: %s, key: %s”, uuid, input, key));
    TimeUnit.SECONDS.sleep(RandomUtil.randomInt(10, 20));
    String value = RandomUtil.randomString(Math.abs(input));
    entity.complete = true;
    entity.completeTime = new Date();
    entity.output = value;
    log.info(String.format(“end task: %s, input: %s, generated: %s”, uuid, input, value));
    redisTemplate.opsForValue().set(key, entity, expire);
    } catch (InterruptedException e) {
    log.warning(e.getMessage());
    e.printStackTrace();
    }
    });
    return uuid;
    }

    @Data
    static class Request {
    Integer input;
    UUID taskId;
    }

    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    static class Response {
    String status;
    Object data;
    UUID taskId;
    Long expire;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class Entity {
    UUID taskId;
    Boolean complete;
    Date beginTime;
    Date completeTime;

    Integer input;
    String output;
    }

    }

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具