1. Executor接口
public interface Executor {
void execute(Runnable command);
}
2. 线程池
Executors的工厂方法可以返回多种线程池:
i. newFixedThreadPool(int nThread),固定大小的线程池,一直维持nThread个线程;
ii. newCachedThreadPool(),根据负载,自动调整线程池线程个数;
iii. newSingleThreadExecutor(),单线程的Executor;
iv. newScheduledThreadPool(int nThread),固定大小的线程池,可以延迟和周期性的执行任务,类似于Timer()(java1.5之后就应该很少用它了);
3. 具有生命周期的executor
ExecutorService一般为执行一组任务,它在没有shutdown前会一直等待。
awaitTermination会阻塞当前调用线程,等待线程池中的线程执行完成,或者超时,注意之前必须先调用shutdown。
public interface ExecutorService extends Executor {
void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
// ... additional convenience methods for task submission
}
4. Callable和Future
Executor的基本执行单元是Runner,但Runner不能返回值,也不好取消等。
接口Callable可以返回计算的值:
public interface Callable<V> {
V call() throws Exception;
}
而Future则可以管理任务的生命周期:
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException,
CancellationException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException,
CancellationException, TimeoutException;
}
ExecutorService.submit()方法会返回一个Future,可以用来获取返回值,或者取消任务。
也可以实例化FutureTask。
5. CompletionService,BlockingQueue和Executor的组合
你可以提交(submit)一组Callable任务,且像队列一样在可用时获取(poll或者taken)计算结果,结果都被包装在Future里。
引用书上的例子:
浏览器渲染HTML页面,先从HTML中获取图片的地址,加入到任务队列中,然后渲染文字,图片到了后,就立即显示。
package org.jamie.demo;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
class ImageData {
private final String data;
public String getData() {
return data;
}
public ImageData(String data) {
super();
this.data = data;
}
}
class ImageLoader {
private Random ran = new Random();
public ImageData load(String src) throws InterruptedException {
long loadTime = 0L;
do {loadTime = ran.nextInt(10000);} //load time between 1 secs and 10 secs.
while (1000 > loadTime);
Thread.sleep(loadTime);
return new ImageData("image data for " + src);
}
}
public class ExecutorServiceDemo {
private ImageLoader imageLoader = new ImageLoader();
public void renderHtmlPage() throws Throwable {
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1);
List<String> imagesSources = scanImageSources();
CompletionService<ImageData> cs = new ExecutorCompletionService<ImageData>(executor);
for (final String src : imagesSources) {
cs.submit(new Callable<ImageData> () {
@Override
public ImageData call() throws Exception {
return imageLoader.load(src);
}
});
}
randerText();
for (int i = 0; i < imagesSources.size(); ++i) {
try {
Future<ImageData> future = cs.poll(2, TimeUnit.SECONDS);
if (null != future) {
ImageData data = future.get();
randerImage(data);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
throw e.getCause();
}
}
executor.shutdown();
}
private void randerImage(ImageData data) {
System.out.println("image of HTML " + data.getData());
}
private void randerText() {
System.out.println("text content of HTML");
}
private List<String> scanImageSources() {
return Arrays.asList(
"/foo.png",
"/bar.png",
"/beauty.jpg",
"/food.png",
"/sex.png",
"/ml.png",
"/boring.png");
}
public static void main(String[] args) throws Throwable {
new ExecutorServiceDemo().renderHtmlPage();
}
}
输出:
写道
text content of HTML
image of HTML image data for /beauty.jpg
image of HTML image data for /foo.png
image of HTML image data for /food.png
image of HTML image data for /bar.png
分享到:
相关推荐
### Java Concurrency Framework 的介绍 #### 一、概述 本文档由 David Holmes 撰写,旨在为初学者提供一个关于 Java Concurrency Framework 的简单介绍。对于那些希望快速掌握 Java 并发编程基础概念的学习者来说...
Separate the thread management from the rest of the application with the Executor framework Solve problems using a parallelized version of the divide and conquer paradigm with the Fork / Join ...
useful mechanisms included in Version 7 of the Java concurrency API, so you will be able to use them directly in your applications, which are as follows: f f t e n . d u o l Basic thread management w....
如何在多线程中执行任务,使用线程池(Thread Pools)和执行器框架(Executor Framework)等高级工具。 7. **取消和关闭(Cancellation and Shutdown)** 处理任务的取消机制,以及在服务停止时的线程安全问题。...
- **Executor Framework**:用于管理和控制线程池的高级API,有助于优化资源使用。 - **Locks and Conditions**:提供了比内置同步更灵活的锁定机制。 - **Concurrent Collections**:专门设计用于支持并发访问的...
The fork/join framework, which is based on the ForkJoinPool class, is an implementation of the Executor interface. It is designed to efficiently run a large number of tasks using a pool of worker ...
执行器框架(Executor Framework Enhancements) `java.util.concurrent`包中的`ExecutorService`接口新增了`invokeAll()`和`invokeAny()`方法,用于执行多个任务并等待任意一个或所有任务完成。 以上只是Java ...
Policy Framework Provisional Policy with New Header API Other API Changes ftplib functools gc hmac http html imaplib inspect io itertools logging math mmap multiprocessing nntplib os...