我们现在在Java中使用多线程通常不会直接用Thread对象了,而是会用到java.util.concurrent包下的ExecutorService类来初始化一个线程池供我们使用。
之前我一直习惯自己维护一个list保存submit的callable task所返回的Future对象。
在主线程中遍历这个list并调用Future的get()方法取到Task的返回值。
但是,我在很多地方会看到一些代码通过CompletionService包装ExecutorService,然后调用其take()方法去取Future对象。以前没研究过这两者之间的区别。
今天看了源代码之后就明白了。
这两者最主要的区别在于submit的task不一定是按照加入自己维护的list顺序完成的。
从list中遍历的每个Future对象并不一定处于完成状态,这时调用get()方法就会被阻塞住,如果系统是设计成每个线程完成后就能根据其结果继续做后面的事,这样对于处于list后面的但是先完成的线程就会增加了额外的等待时间。
而CompletionService的实现是维护一个保存Future对象的BlockingQueue。只有当这个Future对象状态是结束的时候,才会加入到这个Queue中,take()方法其实就是Producer-Consumer中的Consumer。它会从Queue中取出Future对象,如果Queue是空的,就会阻塞在那里,直到有完成的Future对象加入到Queue中。
所以,先完成的必定先被取出。这样就减少了不必要的等待时间。
分享到:
相关推荐
ExecutorService 和 CompletionService 是Java并发处理中的两种工具,它们用于管理和执行多个任务。ExecutorService 是一个接口,它是java.util.concurrent.Executor 接口的扩展,提供了一组方法来管理和控制线程池...
在Java中,通常通过Future和Callable接口实现异步计算,或者使用ExecutorService和CompletionService来管理和控制异步任务。 三、ExecutorService与ThreadPoolExecutor ExecutorService是Java并发框架中的核心接口...
`CompletionService`是Java并发编程中的一个重要工具,它在`ExecutorService`的基础上提供了一种更加高效的方式来管理和处理并发任务的完成结果。`ExecutorService`允许我们提交任务(通常是`Runnable`或`Callable`...
4. `CompletionService`:可能是`ExecutorCompletionService`,它结合了`ExecutorService`和`BlockingQueue`的功能。我们可以使用`CompletionService.take()`方法获取下一个已完成的任务的结果,而不必等待所有任务...
Executor框架包括了Executor、ExecutorService、CompletionService、Future、Callable等接口和类。Executors则是Executor框架的一个工具类,用于创建不同类型的线程池。 在实际应用中,线程池的使用场景广泛,例如...
`CompletionService`接口扩展了`ExecutorService`,它提供了获取已完成任务的便捷方式,特别适用于处理大量并发任务时,需要按完成顺序处理结果的场景。 `Callable`接口类似于`Runnable`,但它可以返回一个结果。`...
`TestCompletionService.java`可能展示了如何结合`ExecutorService`和`Future`来使用`CompletionService`。 4. **ScheduledThreadPoolExecutor**:这个类扩展了`ThreadPoolExecutor`,增加了定时和周期性执行任务的...
例如,我们可以通过`CompletionService`配合`ExecutorService`,使用Lambda表达式创建的任务,实现任务的分批执行和结果的顺序获取。同时,`Future`和`Callable`接口也可以与Lambda表达式结合,用于处理有返回结果的...
看完《think in java》多线程章节,自己写的多线程文档,还结合了其他的相关网络资料。 线程 一....1)为什么要使用线程池 2 2)一个具有线程池的工作队列 3 ...1)ReentrantLock和synchronized关键字的区别 41
它实现了ExecutorService接口和DisposableBean接口,提供了任务提交、处理和线程池管理等功能。 CompletionService是一个接口,用于管理异步任务的完成情况。ExecutorCompletionService类是其实现,它利用线程池...
`ExecutorService`是一个线程池服务,它可以管理和控制多个线程的执行,而`Future`代表了异步计算的结果,可以检查计算是否完成、获取结果或取消任务。`Future`接口提供了`get()`方法来获取结果,该方法会阻塞直到...
使用Future和CompletionService可以实现异步计算和非阻塞的任务调用,并可以实时获取多线程运行结果。这对于Java编程中的多线程编程非常重要。 知识点: 1. 使用Future接口来实现异步计算和非阻塞的任务调用。 2. ...
另外,`CompletionService` 可以帮助管理和协调多个异步任务的完成顺序。 线程池的合理使用对于优化多线程程序的性能至关重要,需要根据系统的并发需求、任务性质等因素来选择合适的线程池类型和参数。同时,避免...
- `java.util.concurrent.CompletionService`:允许获取执行任务的结果,`ExecutorCompletionService` 是其具体实现,结合了 `ExecutorService` 和 `Future`。 5. 线程池执行原理 线程池的执行过程主要包括任务提交...
阐述`interrupt`、`interrupted`和`isInterrupted`方法之间的区别,以及如何处理线程中断的情况。 - **第14章:守护线程** 解释什么是守护线程,以及在哪些情况下应该使用守护线程。 - **第15章:线程池的使用** ...
- `ScheduledExecutorService`:支持定时和周期性任务的ExecutorService。 - `Future`:表示异步计算的结果,可以检查任务是否完成,获取结果或取消任务。 - `CountDownLatch`:用于同步多个线程,让主线程等待...
5. **`java.util.concurrent.CompletionService`和`ForkJoinPool`**:前者提供了异步任务的完成服务,后者是基于分治策略的并行计算框架,适用于大规模并行计算。 6. **线程安全的集合**:`ConcurrentHashMap`、`...
7. CompletionService:提供了一个基于ExecutorService的接口,可以获取已经完成的任务,简化了异步处理的流程。 学习“02-4(马士兵)-多线程并发”这个主题,你需要理解这些核心概念,并通过实践加深对并发编程的...
Java的并发编程框架`java.util.concurrent`包提供了`Executor`接口和相关的实现,包括`ExecutorService`、`CompletionService`等,它们使得并发编程更加简洁高效。`CompletionService`允许获取已完成任务的结果,...