Java 何时使用线程池而不是调用新线程

Java 何时使用线程池而不是调用新线程,java,multithreading,Java,Multithreading,我有一个JAX-RS/Jersey Rest API,它收到一个请求,需要在一个单独的线程中执行额外的工作,但我不确定是否建议使用线程池。我期望有很多对这个API的请求(每天几千个),但我只有一个额外的后台工作 像这样每次只创建一个新线程会不好吗?如有任何建议,将不胜感激。我以前从未使用过线程池 @Get @Path("/myAPI") public Response myCall() { // call load in the background load(); ... //

我有一个JAX-RS/Jersey Rest API,它收到一个请求,需要在一个单独的线程中执行额外的工作,但我不确定是否建议使用线程池。我期望有很多对这个API的请求(每天几千个),但我只有一个额外的后台工作

像这样每次只创建一个新线程会不好吗?如有任何建议,将不胜感激。我以前从未使用过线程池

@Get
@Path("/myAPI")
public Response myCall() {
  // call load in the background
  load();
  ...
  // do main job here
  mainJob();
  ...
}

private void load() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            doSomethingInTheBackground();
        }
    }).start();
}
编辑: 我只是想澄清一下。我只需要一个额外的作业在后台运行。此作业将调用另一个API来记录一些信息,仅此而已。但它必须对每个请求都这样做,我不需要等待响应。这就是为什么我想在一个新的背景线程中这样做

Edit2: 这就是我现在想到的。有谁能告诉我这看起来是否正常(它在本地工作)以及我是否需要关闭执行器(请参阅代码中的注释)


Threadpool是一种很好的处理方法,原因有两个:

1) 您将重用池中的现有线程,这会降低开销 2) 更重要的是,如果系统受到攻击,并且由于池的大小是预先设置的,所以有人试图立即启动数以百万计的会话,您的系统将不会陷入困境


线程池的使用一点也不复杂。请参阅有关线程池的更多信息。再看一看

我建议不要使用您提到的任何一种方法,而是使用JMS队列。您可以轻松地在应用程序中嵌入ActiveMQ实例。首先在后台创建一个或多个单独的使用者线程,以从队列中拾取作业

然后,当收到请求时,只需在JMS队列上推送一条包含作业详细信息的消息。这是一个比摆弄低级线程或线程池更好的体系结构和更具可伸缩性


另请参见:和。

我觉得您根本不需要创建多个线程。 (虽然我可能错了,但我不知道你任务的具体细节)

您是否可以创建一个执行后台工作的线程,并为该线程提供一个
LinkedBlockingQueue
,以存储
doSomethingBackground
调用的参数


如果立即启动后台任务至关重要,即使服务器负载很重,此解决方案也无法工作。但例如,对于我最近的任务(从外部检索文本,将它们返回给API调用方,然后延迟将文本添加到SOLR层),这是一个非常好的解决方案。

我建议您使用线程池,而不是创建新线程。如果您有1000个并发请求,该怎么办?创建1000个线程不是一个好主意。这将消耗您的服务器资源,并影响您的服务响应。您可以在中开始回答。谢谢。我正在考虑使用Executors,但我不确定哪种类型的池适合(单个、缓存、固定等),以及如何确定线程池的大小?很抱歉提出这些基本问题,但正如前面所说的,我以前没有这样做过。@Diyarbakir,正如gioraschc所建议的,这完全取决于你的需要。因此,您必须从某个地方开始,随机应变,并在将来改进您的实现。这就是测试的目的。=]这不是个好主意。让我们假设一个请求处理需要1秒。因此,对X个请求进行排队处理最快需要X秒。如果您的服务器加载了大量请求。。。好。。。作为用户,我将停止使用它;)不,实际上回答用户的线程会立即得到回复。该线程只调用
LinkedBlockingQueue.offer()
// Configuration class
@Bean (name = "executorService")
public ExecutorService executorService() {
    return Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1);
}

// Some other class
@Qualifier("executorService")
@Autowired
private ExecutorService executorService;
....
private void load() {
    executorService.submit(new Runnable() {
        @Override
        public void run() {
            doSomethingInTheBackground();
        }
    });

    // If I enable this I will get a RejectedExecutionException 
    // for a next request.
    // executorService.shutdown();
}