11

我在我编写的许多应用程序中都使用了多线程。在阅读更多内容时,我遇到了ThreadPoolExecutors. 我无法区分这两种情况。

我仍然理解的是,当我有一个任务我想将一个任务分成多个小任务以利用 CPU 并更快地完成工作时,我应该使用多线程。ThreadPoolExecutor当我有一组任务并且每个任务可以相互独立运行时使用。

如果我错了,请纠正我。谢谢

4

5 回答 5

20

AThreadPoolExecutor只是一个高级 API,它使您能够在多个线程中运行任务,而不必处理低级 Thread API。因此,区分多线程和 ThreadPoolExecutor 并没有真正的意义。

s有很多种风格ThreadPoolExecutor,但大多数都允许多个线程并行运行。通常,您会使用Executor Service并使用Executors工厂。

例如,aExecutorService executor = Executors.newFixedThreadPool(10);将在 10 个线程中运行您提交的任务。

于 2012-09-22T20:29:01.620 回答
10

ThreadPoolExecutor是进行多线程的一种方式。它通常在您使用

  1. 有不需要协调的独立操作(虽然没有什么能阻止你协调,但你必须小心)
  2. 希望限制一次执行多少个操作的容量,并且(可选)如果池当前在所有线程中工作,则希望在执行时对操作进行排队。

Java 7 有另一个称为 a 的内置类ForkJoinPool,通常用于 Map-Reduce 类型的操作。例如,可以想象使用 ForkJoinPool 实现合并排序,方法是在每个分叉点将数组拆分为 1/2,等待结果,然后将结果合并在一起。

于 2012-09-22T21:19:22.423 回答
7

线程池(执行器)是多线程的一种形式,特别是单生产者 - 多消费者模式的实现,其中一个线程重复地将工作放入队列中以供一组工作线程执行。它是使用常规线程实现的,并带来了几个好处:

  • 线程匿名——你不需要明确控制哪个线程做什么;只需启动任务,它们将由池处理。
  • 它封装了一个工作队列和线程团队——无需费心实现你自己的线程安全队列和循环线程。
  • 负载平衡 - 由于工作人员在完成之前的任务时会接受新任务,因此只要有足够多的可用任务,工作就会均匀分布。
  • 线程回收 - 只需在开始时创建一个池并继续为其提供任务。无需在每次需要完成工作时都继续启动和终止线程。

鉴于上述情况,池确实适用于通常相互独立且通常短暂的任务(长时间的 I/O 操作只会占用池中无法执行其他任务的线程)。

于 2012-09-22T21:17:40.747 回答
1

ThreadPoolExecutor 是多线程的一种形式,使用比直接使用线程更简单的 API,在线程中确实可以提交任务。但是,任务可以提交其他任务,因此它们不必是独立的。至于将任务划分为子任务,你可能会想到 JDK7 中新的 fork/join API。

于 2012-09-22T20:28:21.293 回答
1

来自ThreadPoolExecutor的源代码文档

/*
 * <p>Thread pools address two different problems: they usually
 * provide improved performance when executing large numbers of
 * asynchronous tasks, due to reduced per-task invocation overhead,
 * and they provide a means of bounding and managing the resources,
 * including threads, consumed when executing a collection of tasks.
 * Each {@code ThreadPoolExecutor} also maintains some basic
 * statistics, such as the number of completed tasks.
 *
 * <p>To be useful across a wide range of contexts, this class
 * provides many adjustable parameters and extensibility
 * hooks. However, programmers are urged to use the more convenient
 * {@link Executors} factory methods {@link
 * Executors#newCachedThreadPool} (unbounded thread pool, with
 * automatic thread reclamation), {@link Executors#newFixedThreadPool}
 * (fixed size thread pool) and {@link
 * Executors#newSingleThreadExecutor} (single background thread), that
 * preconfigure settings for the most common usage
 * scenarios.
 */

ThreadPoolExecutor是实现并发的一种方式。实现并发的方法有很多:

Executors框架提供了不同的 API。下面列出了一些重要的 API。

static ExecutorService  newFixedThreadPool(int nThreads)

创建一个线程池,该线程池重用在共享无界队列上运行的固定数量的线程。

static ExecutorService  newCachedThreadPool()

创建一个线程池,根据需要创建新线程,但在可用时将重用以前构造的线程。

static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

创建一个线程池,可以安排命令在给定延迟后运行,或定期执行。

static ExecutorService  newWorkStealingPool()

创建一个工作窃取线程池,使用所有可用处理器作为其目标并行度级别。

看看下面的 SE 问题:

java Fork/Join 池、ExecutorService 和 CountDownLatch

如何正确使用 Java Executor?

于 2016-02-29T03:37:16.473 回答