在我的项目中,我要求用户调用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());
由于MyAsyncSupplier和MyAsyncConsumer类存在一些对象分配问题,因此上述代码无法正常工作。我进一步调试了代码,并修复了这些代码。
实际上,不需要执行者提交。
@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();
}
答案 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