Executor基于生产者-消费者模式,提交任务(Runnable)的操作相当于生产者(生成待完成的工作单元),执行任务的线程相当于消费者(执行完这些工作单元)。
每当看到下面这种形式的代码时:
new Thread(runnable).start()
并且你希望获得一种更灵活的执行策略,请考虑使用Executor来替代Thread。
1. 线程池
在线程池中执行任务比为每个任务分配一个线程优势更多。通过重用现有的线程而不是创建新线程,可以在处理多个请求时分摊在线程创建和销毁过程中产生的巨大开销。另一个额外的好处是:当请求到达时,工作线程通常已经存在,因此不会由于等待创建线程而延迟任务的执行,从而提高了响应性。通过适当调整线程池的大小,可以创建足够多的线程以便使处理器保持忙碌状态,同时还可以防止过多线程相互竞争资源而使应用程序耗尽内存或者失败。
API提供了一个灵活的线程池以及一些有用的默认配置。可以通过调用Executors中的静态工厂方法之一来创建线程池:
- newFixedThreadPool将创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。在任意点,在大多数 nThreads 线程会处于处理任务的活动状态。如果在所有线程处于活动状态时提交附加任务,则在有可用线程之前,附加任务将在队列中等待。如果在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要)。在某个线程被显式地关闭之前,池中的线程将一直存在。
- newCachedThreadPool将创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们,线程池的规模不存在任何限制。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。注意,可以使用 ThreadPoolExecutor 构造方法创建具有类似属性但细节不同(例如超时参数)的线程池。
- newSingleThreadExecutor将会创建一个单线程的Executor,它创建单个工作者线程来执行任务,如果这个线程异常结束,会创建另一个线程来替代。newSingleThreadExecutor能确保依照任务在队列中的顺序来串行执行(例如FIFO/LIFO/优先级)
- newScheduledThreadPool创建ScheduledExecutorService,它是一个固定长度的线程池,而且以延迟或定时的方式来执行任务,类似于Timer。
2. 任务执行完通知(CompletionService)
CompletionService接口用于执行多个任务,通过阻塞的take方法获得已经完成的任务(当任务完成就将对应的Future放入到一个阻塞队列中)。构造函数需要传入一个Executor。
将生产新的异步任务与使用已完成任务的结果分离开来的服务。生产者submit执行的任务。使用者take已完成的任务,并按照完成这些任务的顺序处理它们的结果。例如,CompletionService可以用来管理异步IO,执行读操作的任务作为程序或系统的一部分提交,然后,当完成读操作时,会在程序的不同部分执行其他操作,执行操作的顺序可能与所请求的顺序不同。通常,CompletionService依赖于一个单独的Executor来实际执行任务,在这种情况下,CompletionService只管理一个内部完成队列。ExecutorCompletionService类提供了此方法的一个实现。
内存一致性效果:线程中向 CompletionService 提交任务之前的操作 happen-before 该任务执行的操作,后者依次 happen-before 紧跟在从对应 take() 成功返回的操作。
3. 预定时间内执行多个任务
创建N个任务,将其提交到一个线程池,保留N个Future,并使用限时的get方法通过Future串行地获取每一个结果,完成这样的任务还有另一个更简单的方法-invokeAll
Please refer to API of ExecutorService。
相关推荐
Executor框架是Java并发编程的核心组件,它在Java 5中被引入,极大地简化了多线程编程。这个框架是基于`java.util.concurrent`包中的接口和类构建的,旨在提供线程池服务、任务调度以及并发执行任务的能力。Executor...
在`Executor`框架中,`ExecutorService`是核心接口,它扩展了`Executor`接口并添加了一些用于管理和控制线程池的方法,如提交任务、关闭线程池等。Android开发者通常会使用`ThreadPoolExecutor`或`...
Java通过引入Executor框架,为并发任务的执行提供了一种高效、灵活的管理机制。本文将深入探讨Executor框架的设计哲学、核心组件,并结合实例演示如何利用这一框架提升程序的性能和响应性。 注意事项和最佳实践 合理...
该文档详细记录了Executor框架结构、使用示意图、ThreadPoolExecutor使用示例、线程池原理分析、几种常见线程池(FixedThreadPool、SingleThreadExecutor、CachedThreadPool)的详解以及线程池大小确定等内容
Java中的Executor框架是多线程编程的一个重要组成部分,它始于JDK5,目的是为了更好地管理和控制线程的执行。Executor框架的设计理念是将任务(工作单元)与执行机制分离,从而提高了程序的可扩展性和灵活性。 1. *...
java.线程池与Executor框架(解决方案).md
Executor框架提供了一种执行异步任务的方法,它允许开发者将任务提交给线程池,而无需直接管理线程的生命周期。这一框架的核心组件包括: - **Executor**:一个接口,定义了执行提交的Runnable任务的方法。 - **...
Java的Executor框架是Java 1.5引入的用于管理和控制多线程的一种机制,它旨在解决直接使用`new Thread(…).start()`方法创建线程所带来的问题。在传统的多线程编程中,直接创建和销毁线程会导致大量开销,且无法有效...
本文将详细解读Java中Executor框架的线程池原理和源码,同时探讨线程池的调优和监控方法。 首先,线程池的主要作用包括:避免了线程的无限制创建,减少了线程创建和销毁的开销,提升系统性能;实现任务的快速响应,...
Java并发之线程池Executor框架的深入理解 Java中的线程池Executor框架是Java并发编程中的一种常见机制,用于管理和执行异步任务。通过使用线程池,可以大大减少线程的创建和销毁开销,从而提高系统的性能和稳定性。...
ScheduledThreadPoolExecutor 类是 Executor 框架的另一个核心实现类,提供了一个线程池来执行延迟任务。ScheduledThreadPoolExecutor 类可以根据需要创建和销毁线程,以避免资源浪费。开发者可以使用 ...
### 针对Executor框架与线程共享数据的深入探讨 #### 1. Executor框架的重要性与优势 在Java并发编程领域中,Executor框架扮演着一个非常核心的角色。它为开发者提供了一个高效且易于使用的线程池管理方案。下面将...
项目中碰到的,记录一下
开发中碰到的
3. **线程池接口与实现**:在Java中,`java.util.concurrent.Executor` 是线程池的顶级接口,它定义了执行任务的基本方法。`ExecutorService` 是实际的线程池接口,提供了更丰富的管理和控制线程池的方法。`...
1、Executor框架简介 从JDK5开始,工作单元和执行机制隔离开来,工作单元包括Runnable和Callable,执行机制由Executor提供。 调用关系:Java线程一对一映射到本地操作系统的系统线程,当多线程程序分解若干...
SparkTask 的执行流程是 Spark 框架中一个非常重要的组件,负责将用户提交的任务转换为可执行的 Task,并将其提交到 Executor 的线程池中执行。本文将详细讲解 SparkTask 的执行流程,并对 TaskRunner、ResultTask、...
Java并发框架中的Executor服务是Java 1.5引入的核心组件,位于`java.util.concurrent`包下,极大地简化了多线程编程。Executor接口虽然历史悠久,但其重要性不言而喻,很多开发者对其背后的原理并不十分了解。本文将...