猿问

java后台耗时任务多线程返回结果

@RequestMapping(value = "ehr", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON)
    @ResponseBody
    public User getUser() {
        User u = new User();
        Future<User> future = poolTaskExecutor.submit(ehrDownloadTask);
        boolean flag = future.isDone();
        while (!flag) {
            u.setMsg("未完成");
            return u;
        }
        try {
            u = future.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("任务完成!");
        return u;
    }
    

假设我我请求一个耗时任务放到线程池里执行,我想如果没执行完返回前台未完成,前台可以刷新页面显示完没完成,但是一刷新,我就又新起了一个线程去执行,所以一直返回未完成。请教下这个怎么写?

月关宝盒
浏览 1333回答 2
微课
2回答

烙印99

写个简单实现: private static Map<String,Future<User>> futures = new HashMap<>(); @RequestMapping(value = "ehr", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON) @ResponseBody public User getUser(HttpServletRequest request, HttpServletResponse response) { String sessionID = request.getSession().getId(); User u = new User(); u.setMsg("未完成"); if(futures.containsKey(sessionID)) { Future<User> userFuture = futures.get(sessionID); if(userFuture.isDone()) { try { u = userFuture.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } futures.remove(sessionID); } } else { Future<User> future = poolTaskExecutor.submit(ehrDownloadTask); futures.put(sessionID,future); } return u; } 前台轮训直到正确返回。Key你可以用我这样的SessionID,也可以自己根据逻辑生成如果是分布式Tomcat可以用Redis代替HashMap

天涯尽头无女友

需要注意一点 线程安全 HashMap不具备线程安全,这么写会出问题,建议使用ConcurrentHashMap其次,你这个可以考虑用定时任务处理表里的记录,tableA.doneStatus这种 这个时候前端就走查询逻辑就好了,一般的业务场景还是系统自动触发处理,用户查询了你再处理,我的感觉还是不太好以上
随时随地看视频慕课网APP

相关分类

Java
我要回答