Concurrency>cat FutureRenderer.java
import java.util.*;
import java.util.concurrent.*;
/**
* FutureRenderer
* <p/>
* Waiting for image download with \Future
*/
public abstract class FutureRenderer {
private final ExecutorService executor = Executors.newCachedThreadPool();
public static void main(String[] args) {
FutureRenderer futureRenderer = new FutureRenderer() {
@Override
void renderText(CharSequence s) {
try {
Thread.sleep(2000);
System.out.println(Thread.currentThread().toString() + " renders text finished.");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("rendering text: " + s);
}
@Override
List<ImageInfo> scanForImageInfo(CharSequence s) {
List<ImageInfo> imageInfos = new ArrayList<>();
for(int i = 0; i < 5; i++) {
imageInfos.add(new ImageInfo() {
@Override
public ImageData downloadImage() {
try {
Thread.sleep(2000);
System.out.println(Thread.currentThread().toString() + " downloads image complete.");
} catch (InterruptedException e) {
e.printStackTrace();
}
return new ImageData() {};
}
});
}
return imageInfos;
}
@Override
void renderImage(ImageData i) {
System.out.println("rendering image: " + i.toString());
}
};
futureRenderer.renderPage("page HTML code here");
}
void renderPage(CharSequence source) {
final List<ImageInfo> imageInfos = scanForImageInfo(source);
Future<List<ImageData>> future = executor.submit(() -> {
List<ImageData> result = new ArrayList<ImageData>();
for (ImageInfo imageInfo : imageInfos)
result.add(imageInfo.downloadImage());
return result;
});
renderText(source);
renderText(source);
try {
List<ImageData> imageData = future.get();
for (ImageData data : imageData)
renderImage(data);
} catch (InterruptedException e) {
// Re-assert the thread's interrupted status
Thread.currentThread().interrupt();
// We don't need the result, so cancel the task too
future.cancel(true);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
executor.shutdown();
try {
executor.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
interface ImageData {
}
interface ImageInfo {
ImageData downloadImage();
}
abstract void renderText(CharSequence s);
abstract List<ImageInfo> scanForImageInfo(CharSequence s);
abstract void renderImage(ImageData i);
}
Concurrency>javac FutureRenderer.java
Concurrency>date; java FutureRenderer; date
Sat Jul 15 16:37:23 EDT 2017
Thread[pool-1-thread-1,5,main] downloads image complete.
Thread[main,5,main] renders text finished.
rendering text: page HTML code here
Thread[main,5,main] renders text finished.
rendering text: page HTML code here
Thread[pool-1-thread-1,5,main] downloads image complete.
Thread[pool-1-thread-1,5,main] downloads image complete.
Thread[pool-1-thread-1,5,main] downloads image complete.
Thread[pool-1-thread-1,5,main] downloads image complete.
rendering image: FutureRenderer$1$1$1@2ff4acd0
rendering image: FutureRenderer$1$1$1@54bedef2
rendering image: FutureRenderer$1$1$1@5caf905d
rendering image: FutureRenderer$1$1$1@27716f4
rendering image: FutureRenderer$1$1$1@8efb846
Sat Jul 15 16:37:34 EDT 2017
Concurrency>