在 JAX-RS 中实现线程池 api

Implementing threadpool in JAX-RS api

在 JAX-RS api 中,我想实现一个线程池以将新传入请求分配给池中的新线程。 我的 api 目前看起来像这样:

@Service
@Path("/")
public class SampleService {
    @POST
    @Path("/pass")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response sampleApi(Incoming bean){
        //do some processing on bean
        File file = getUserData(bean);
        //do some processing on file
        return Response.status(200).entity("OK").build();
    }

    private File getUserData(Incoming bean){
        //fetch data from external service through SOAP
        //put in one file and return the file
    }
}

我的线程池实现如下所示

@Component
public class OnlineThreadPool {

    private static ThreadPoolExecutor pool;

    @PostConstruct
    public void initialize(){
        pool = new ThreadPoolExecutor(3, 20, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3));
    }

    public ThreadPoolExecutor getThreadPoolExecutor(){
        return pool;
    }

    @PreDestroy
    public void cleanUp(){
        pool.shutdown();
    }
}

我想设置一个异步 api 以便在 POST 请求此 api 时,从线程池中获取新线程并将请求放入新线程并响应不等待线程完成请求的处理就返回。

任何关于如何实现它的资源都会有很大帮助。

编辑: 感谢 thilo 的回答,正在为每个请求创建新线程,但它在整个处理之前终止。但是一旦调用这个新线程的父线程终止,子线程也终止。如何分离这些父子线程?

编辑: 由于线程执行未完成,我的流程中出现空指针异常。因为直到现在我还没有给出异常处理程序,所以它没有显示任何错误,只是在没有任何异常消息的情况下停止。

@POST
@Path("/pass")
@Consumes(MediaType.APPLICATION_JSON)
public Response sampleApi(final Incoming bean){
    onlineThreadPool.getThreadPoolExecutor().submit(new Runnable(){
       @Override public void run(){
          //do some processing on bean
          File file = getUserData(bean);
         //do some processing on file
       }});
    return Response.status(200).entity("OK").build();
}

它应该是这样的。请注意,我正在使用构造函数注入来注入您的 OnlineThreadPool 依赖项,并使用 Java 8 lambda 来创建 Runnable.

@Service
@Path("/")
public class SampleService {

     private OnlineThreadPool pool;

     public SampleService(OnlineThreadPool pool) {
         this.pool = pool;
     } //constructor injection 

     @POST
     @Path("/pass")
     @Consumes(MediaType.APPLICATION_JSON)
     public Response sampleApi(Incoming bean){
         pool.getThreadPoolExecutor().submit(() -> {
              File file = getUserData(bean);
              //some other processing
         });
         return Response.status(200).entity("OK").build();
     }
}