Java中的线程池有什么用?

发布于 2024-09-10 09:48:07 字数 30 浏览 7 评论 0原文

线程池有什么用?现实世界中有一个很好的例子吗?

What is the use of a Thread pool? Is there a good real world example?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

小鸟爱天空丶 2024-09-17 09:48:07

线程池是最初创建的一组线程,用于等待作业并执行它们。我们的想法是让线程始终存在,这样我们就不必每次都花费额外的时间来创建它们。当我们知道有一系列工作需要处理时,即使有时可能没有工作,它们也是合适的。

这是来自维基百科的漂亮图表:
替代文本

A thread pool is a group of threads initially created that waits for jobs and executes them. The idea is to have the threads always existing, so that we won't have to pay overhead time for creating them every time. They are appropriate when we know there's a stream of jobs to process, even though there could be some time when there are no jobs.

Here's a nice diagram from Wikipedia:
alt text

傻比既视感 2024-09-17 09:48:07

Java 教程中的 线程池 有一个很好的概述:

使用工作线程可以最大限度地减少线程创建带来的开销。线程对象使用大量内存,在大型应用程序中,分配和释放许多线程对象会产生大量内存管理开销。

Thread Pools from the Java Tutorials has a good overview:

Using worker threads minimizes the overhead due to thread creation. Thread objects use a significant amount of memory, and in a large-scale application, allocating and deallocating many thread objects creates a significant memory management overhead.

戏舞 2024-09-17 09:48:07

线程池是一个已创建的工作线程池,准备完成工作。它创建Thread并管理它们。线程池不是创建线程并在任务完成后丢弃它们,而是以工作线程的形式重用线程。

为什么?

因为创建线程是一个耗时的过程,并且会延迟请求处理。它还根据每个 JVM 允许的线程数量来限制客户端数量,这显然是一个有限的数量。


使用Executor框架创建固定大小的线程池-

Java 5引入了一个全功能的内置线程池框架,通常称为Executor框架

使用 Java 5 Executor 框架创建固定大小的线程池非常容易,因为 Executors 类提供了静态工厂方法。您需要做的就是定义要并发执行的任务,然后将该任务提交给 ExecutorService。

从这里开始,线程池将负责如何执行该任务;它可以由任何空闲工作线程执行。

public class ThreadPoolExample {
    public static void main(String args[]) {
       ExecutorService service = Executors.newFixedThreadPool(10); //create 10 worker threads in Thread Pool
       for (int i =0; i<100; i++){
           service.submit(new Task(i)); //submit that to be done 
       }
       service.shutdown();
    }  
}

final class Task implements Runnable {
    private int taskId;  
    public Task(int id){
        this.taskId = id;
    }
  
    @Override
    public void run() {
        System.out.println("Task ID : " + this.taskId +" performed by " 
                           + Thread.currentThread().getName());
    }  
}

Output:
Task ID : 0 performed by pool-1-thread-1
Task ID : 3 performed by pool-1-thread-4
Task ID : 2 performed by pool-1-thread-3
Task ID : 1 performed by pool-1-thread-2
Task ID : 5 performed by pool-1-thread-6
Task ID : 4 performed by pool-1-thread-5

*Output may vary from system to system

Thread pool is a pool of already created worker thread ready to do the job. It creates Thread and manage them. Instead of creating Thread and discarding them once task is done, thread-pool reuses threads in form of worker thread.

Why?

Because creation of Thread is time consuming process and it delays request processing. It also limits number of clients based upon how many thread per JVM is allowed, which is obviously a limited number.


Create fixed size thread pool using Executor framework -

Java 5 introduced a full feature built-in Thread Pool framework commonly known as Executor framework.

Creating fixed size thread pool using Java 5 Executor framework is pretty easy because of static factory methods provided by Executors class. All you need to do is define your task which you want to execute concurrently and than submit that task to ExecutorService.

From here, Thread pool will take care of how to execute that task; it can be executed by any free worker thread.

public class ThreadPoolExample {
    public static void main(String args[]) {
       ExecutorService service = Executors.newFixedThreadPool(10); //create 10 worker threads in Thread Pool
       for (int i =0; i<100; i++){
           service.submit(new Task(i)); //submit that to be done 
       }
       service.shutdown();
    }  
}

final class Task implements Runnable {
    private int taskId;  
    public Task(int id){
        this.taskId = id;
    }
  
    @Override
    public void run() {
        System.out.println("Task ID : " + this.taskId +" performed by " 
                           + Thread.currentThread().getName());
    }  
}

Output:
Task ID : 0 performed by pool-1-thread-1
Task ID : 3 performed by pool-1-thread-4
Task ID : 2 performed by pool-1-thread-3
Task ID : 1 performed by pool-1-thread-2
Task ID : 5 performed by pool-1-thread-6
Task ID : 4 performed by pool-1-thread-5

*Output may vary from system to system
苍景流年 2024-09-17 09:48:07

简单的 Google 搜索就会得到有关 Java 线程池和一般线程池的大量信息。

以下是一些有用的链接:

A simple Google search will result in a wealth of information regarding Java thread pools and thread pools in general.

Here are some helpful links:

冰之心 2024-09-17 09:48:07

线程池仅在无法确定/预测客户端请求的数量/出现的服务器-客户端类型的情况下有用。

在这种情况下,每次发出客户端请求时创建一个新线程有两个缺点:

1) 线程创建的运行时延迟:
创建线程需要一些时间,因此实际作业不会在请求到来时立即开始。客户端可能会注意到轻微的延迟。

这个标准在交互式系统中至关重要,因为客户期望立即采取行动。

2) 系统资源的不受控制的使用:
线程会消耗系统资源(内存等),因此,如果出现前所未有的客户端请求流,系统可能会耗尽资源。

线程池通过以下方式解决上述问题:
1) 在服务器启动时创建指定数量的线程,而不是在运行时创建它们。
2) 限制在任何给定时间运行的线程数量。

注意:以上内容适用于固定大小的线程池。

Thread Pools are useful only in a Server-client kind of situation where the number/occurrence of client requests cannot be determined/predicted.

In this scenario, creating a new Thread each time a client request is made has two dis-advantages:

1) Run time latency for thread creation:
Creation of a thread requires some time, thus the actual job does not start as soon as the request comes in. The client may notice a slight delay.

This criteria is crucial in interactive systems, where the client expects an immediate action.

2) Uncontrolled use of System Resources:
Threads consume system resources (memory etc.), thus the system may run out of resources in case there is an unprecedented flow of client requests.

Thread pools address the above concerns by:
1) Creating specified number of threads on server start-up instead of creating them during the run-time.
2) Limiting the number of threads that are running at any given time.

Note: The above is applicable for Thread Pools of Fixed Sizes.

夏夜暖风 2024-09-17 09:48:07

您可以假设线程是实际的工作人员,而线程池是工作人员组。
您可以出于各种原因(例如优先级、目的等)创建多个组。
因此,虽然一个池可能用于后台计划、电子邮件广播等通用任务,但可能会有一个事务处理池来同时处理多个事务。对于执行者服务,我确信您不希望在其他非关键活动(例如广播确认电子邮件或数据库维护活动)未完成后延迟事务作业的完成。
您可以将它们分成池并独立维护它们。
这是一个非常简单的答案,没有涉及技术术语。
问候,
康泰

You may assume Threads to be actual workers and Thread Pools to be group of workers.
You may create multiple groups for various reasons like priority, purpose, etc.
So, while one pool may be for general purpose tasks like background schedules, email broadcasting, etc. there might be a transaction processing pool to simultaneously process multiple transactions. In case of an Executor Service, I am sure you would not like to delay the transactional jobs to be completed after other non-critical activities like broadcasting confirmation emails or database maintenance activities are not completed.
You may segregate them into pools and maintain them independently.
That's a very simplistic answer without getting into technical jargons.
Regards,
KT

↘紸啶 2024-09-17 09:48:07

已经有很好的答案来解释它,但让我们理解它
举个例子:

没有线程池的问题:考虑一个 Web 服务器应用程序,其中每个 HTTP 请求都由单独的线程处理。如果应用程序只是为每个新的 HTTP 请求创建一个新线程,并且系统收到的请求数量超出了它可以立即处理的数量,那么当所有这些线程的开销超过系统的容量时,应用程序将突然停止响应所有请求。

使用线程池的解决方案:由于可创建的线程数量受到限制,应用程序不会在 HTTP 请求传入时尽快为其提供服务,但会尽快为它们提供服务系统可以维持。

有关更多详细信息(所有线程的开销):为什么创建据说线程很贵?

Already great answers are there to explain it but Lets understand it
with an example:

Problem without thread pool: Consider a web server application where each HTTP request is handled by a separate thread. If the application simply creates a new thread for every new HTTP request, and the system receives more requests than it can handle immediately, the application will suddenly stop responding to all requests when the overhead of all those threads exceed the capacity of the system.

Solution with thread pool: With a limit on the number of the threads that can be created, the application will not be servicing HTTP requests as quickly as they come in, but it will be servicing them as quickly as the system can sustain.

For more details(overhead of all the threads): Why is creating a Thread said to be expensive?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文