【问题标题】:Implementing threadpool in JAX-RS api在 JAX-RS api 中实现线程池
【发布时间】:2016-01-30 11:44:01
【问题描述】:

在 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,以便在对该api的POST请求时,从线程池中获取新线程并将req放入新线程中并返回响应而不等待线程完成请求的处理.

任何有关如何实现这一点的资源都会有很大帮助。

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

编辑: 由于线程执行未完成,我的流程中有一个空指针异常。由于我到目前为止还没有给出异常处理程序,它没有显示任何错误,只是停止而没有任何异常消息。

【问题讨论】:

  • 那么HTTP客户端不需要在响应中得到结果吗?立即发送 HTTP 响应,然后在后台继续处理?
  • 如果是这样,请将 OnlineThreadPool 注入到 SampleService 中,并在 sampleAPI 方法中将 Runnable 提交给 getThreadPoolExecutor。并且不要将池设为静态。
  • 是的,客户端不需要等待处理完成,它可以立即响应。要提交 runnable ,我需要在我的班级中实现 runnable 吗?是的,我不应该将池设为静态吗?

标签: java multithreading asynchronous jax-rs threadpoolexecutor


【解决方案1】:
@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();
}

【讨论】:

  • 如果你使用的是 Java8,你可以删除很多样板文件。
  • 哦。因此,根据请求,启动新线程并在其中完成处理,但是一旦执行返回,新线程就会停止处理..我是否需要添加一些关于从父线程分离的地方?
  • 没有“新线程”(除非池很忙)它只使用池中的一个。当方法返回时,处理不应停止。
【解决方案2】:

这就是它应该的样子。请注意,我使用构造函数注入来注入您的 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();
     }
}

【讨论】:

    猜你喜欢
    • 2017-12-11
    • 1970-01-01
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    • 2011-11-28
    • 1970-01-01
    • 2015-04-18
    • 2013-06-26
    相关资源
    最近更新 更多