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

查看:476
本文介绍了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;
    }
    

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

解决方案

写个简单实现:

    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

这篇关于java后台耗时任务多线程返回结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆