Jersey Rest API立即返回,长任务继续

时间:2018-10-08 18:57:51

标签: java multithreading java-ee jersey java-threads

在我的项目中,我要求用户调用REST API-POST操作来执行长时间等待的任务,现在,我们要立即通知用户说“任务已接受”,而不是让用户等待,后台触发另一个线程来执行长期任务。

我已经尝试了以下代码,但是从API返回其他线程的那一刻起,就不会记录任何消息或执行任何任务。我在这里想念什么。

@POST
@Path("/longtask")
@Consumes(MediaType.APPLICATION_JSON)
public Response longTask() {
    LOGGER.info("longTask started by Thread: "+Thread.currentThread().getName());
    executor.submit(
            new Runnable() {
                @Override
                public void run() {
                    new AsyncService().longTask();
                }
            });       
    LOGGER.info("longTask completed by Thread: "+Thread.currentThread().getName());
    return Response.ok(new MyResponse<>("Task Accepted")).build();
}

AsyncService

public class AsyncService {

    /**
     *
     */
    public void longTask(){
        LOGGER.info("AsyncService - longTask() Started: "+Thread.currentThread().getName());
        try{
            //Tried thenAcceptAsync as well
            CompletableFuture.supplyAsync(new MyAsyncSupplier()).thenAccept(new MyAsyncConsumer());
        }finally{
            LOGGER.info("AsyncService - longTask() Completed: "+Thread.currentThread().getName());
        }

    }   

}

MyAsyncSupplier()和MyAsyncConsumer()是一些调用数据库并执行长时间等待任务的任务。 不打印MyAsyncSupplier()和MyAsyncConsumer()下的记录器。我只是通过一个示例Java项目和main()方法尝试了相同的操作,并且发生了相同的事情。主机完成System.out的那一刻不打印。

[744832b5-deed-4043-11-111] [myproject] 2018-10-08 18:19:16,836 [http-nio-8080-exec-31] INFO  mypackage.MyResource - longTask started by Thread: http-nio-8080-exec-31
[744832b5-deed-4043-11-111] [myproject] 2018-10-08 18:19:16,836 [http-nio-8080-exec-31] INFO  mypackage.MyResource - longTask completed by Thread: http-nio-8080-exec-31
[] [] 2018-10-08 18:19:16,837 [pool-64-thread-1] INFO  mypackage.AsyncService - AsyncService - longTask() Started: pool-64-thread-1
[744832b5-deed-4043-11-11] [myproject] 2018-10-08 18:19:16,844 [http-nio-8080-exec-31] DEBUG mypackage.InitializationResponseFilter - Media Type set to : application/json 

如何使此任务继续?

CompletableFuture.supplyAsync(new MyAsyncSupplier()).thenAccept(new MyAsyncConsumer());

更新1:

由于MyAsyncSupplier和MyAsyncConsumer类存在一些对象分配问题,因此上述代码无法正常工作。我进一步调试了代​​码,并修复了这些代码。

更新2:

实际上,不需要执行者提交。

@POST
@Path("/longtask")
@Consumes(MediaType.APPLICATION_JSON)
public Response longTask() {
    LOGGER.info("longTask started by Thread: "+Thread.currentThread().getName());
    new AsyncService().longTask();
    LOGGER.info("longTask completed by Thread: "+Thread.currentThread().getName());
    return Response.ok(new MyResponse<>("Task Accepted")).build();
}

1 个答案:

答案 0 :(得分:-1)

我认为您发布的代码可以正常运行。也许您对MyAsyncSupplier和MyAsyncSupplier的实现是错误的。这是我的实现方案。

public class FunFun {
    ExecutorService executor = Executors.newFixedThreadPool(2);

    public static void main(String[] args) {
        FunFun f = new FunFun();
        f.longTask();
        f.shutdown();
//        Scanner scanner = new Scanner(System.in); changed to use shutdown.
//        scanner.nextLine();
//        System.exit(0);
    }

    public void shutdown() {
        executor.shutdown();
    }

    public String longTask() {
        System.out.println("longTask started by Thread: "+Thread.currentThread().getName());
        executor.submit(
                new Runnable() {
                    @Override
                    public void run() {
                        new AsyncService().longTask();
                    }
                });
        System.out.println("longTask completed by Thread: "+Thread.currentThread().getName());
        return "Task Accepted";
    }

    public class AsyncService {
        public void longTask(){
            System.out.println("AsyncService - longTask() Started: "+Thread.currentThread().getName());
            try{
                //Tried thenAcceptAsync as well
                CompletableFuture.supplyAsync(new MyAsyncSupplier()).   thenAcceptAsync(new MyAsyncConsumer());
            }finally{
                System.out.println("AsyncService - longTask() Completed: "+Thread.currentThread().getName());
            }
        }
    }

    public class MyAsyncSupplier implements Supplier<String>{

        @Override
        public String get() {
            System.out.println("Supplying Food");
            return "Food";
        }

    }

    public class MyAsyncConsumer implements Consumer<String>{

        @Override
        public void accept(String t) {
            System.out.println("Nom Nom " + t);
        }
    }
}

输出:

longTask started by Thread: main
longTask completed by Thread: main
AsyncService - longTask() Started: pool-1-thread-1
Supplying Food
Nom Nom Food
AsyncService - longTask() Completed: pool-1-thread-1