Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Jersey Rest API立即返回,长任务继续_Java_Multithreading_Jakarta Ee_Jersey_Java Threads - Fatal编程技术网

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

Java Jersey Rest API立即返回,长任务继续,java,multithreading,jakarta-ee,jersey,java-threads,Java,Multithreading,Jakarta Ee,Jersey,Java Threads,我在我的项目中有一个要求,用户调用RESTAPI-POST操作来执行一个长时间等待的任务,现在我们不想让用户等待,而是要立即通知用户任务已接受,并在后台启动另一个线程来执行长时间任务 我已经尝试了下面的代码,但是当API返回其他线程时,不会记录任何消息或执行任何任务。我错过了什么 @POST @Path("/longtask") @Consumes(MediaType.APPLICATION_JSON) public Response longTask() { LOGGER.info("

我在我的项目中有一个要求,用户调用RESTAPI-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();
}
MyAsyncSupplier和MyAsyncConsumer是调用DB并执行长等待任务的任务。 未打印MyAsyncSupplier和MyAsyncConsumer下的记录器。我用一个示例java项目和main方法尝试了同样的方法,同样的情况也发生了。主设备完成系统的那一刻。输出不打印

[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();
}

我认为你发布的代码很好,工作正常。也许您对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);
        }
    }
}

我有点困惑。您说/longstask返回后没有记录任何内容,但在您的日志中可以清楚地看到,在打印完完整消息后,AsyncService将启动。你还记得在主电路中设置一个等待或循环来保持它的活力吗。一旦完成main,JVM就会被杀死。这就是为什么你的简单java项目不起作用的原因。日志记录者在打印出完整的未来之前。MySupplier和MyConsumer提供的once不会记录在数据库中并执行。如果我加上等待,这难道不会让主线等待吗?如果你投了反对票,至少告诉我为什么,这样我可以从中吸取教训。查尔斯,我不知道谁/为什么投了反对票。但是我觉得不需要扫描器和System.exit0代码。在这种情况下,因为你有一个执行器,如果你没有System.exit0,它将保持程序运行;更好的解决办法是关闭执行器。还注意到thenAccept未使用ThenAcceptSync。您是对的,longTask不需要执行器,但您可以在SupplySync和AccpetAsync调用中使用它,这将为您提供更多的控制。此外,如果你觉得这篇文章有帮助,你可以投票,甚至接受答案。没有压力,但我喜欢rep:
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