Java并发编程

来源:互联网 发布:澜本嫁衣 知乎 编辑:程序博客网 时间:2024/05/19 14:56
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
 * 示例-异步渲染页面的文字和图片信息
 * @author lufang
public abstract class PageRenderer {
    private final ExecutorService executor = createExecutorService();
     * 渲染页面
     * @param source
     *            页面源码
    public void renderPage(CharSequence source) {
        final List<String> imagePaths = scanForImagePaths(source);
        Callable<List<ImageData>> task = new Callable<List<ImageData>>() {
            public List<ImageData> call() {
                List<ImageData> result = new ArrayList<ImageData>();
                for (String path : imagePaths)
                    result.add(downloadImage(path));
                return result;
        Future<List<ImageData>> future = executor.submit(task);
        renderText(source);
        try {
            List<ImageData> imageData = future.get();
            for (ImageData data : imageData)
                renderImage(data);
        } catch (InterruptedException e) {
            // 因为在得到这个异常的同时,线程的中断状态已经被清除了,需要保留线程的中断状态,则需要调用Thread.currentThread().interrupt()
            Thread.currentThread().interrupt();
            // 取消任务
            future.cancel(true);
        } catch (ExecutionException e) {
            launderThrowable(e.getCause());
        } finally {http://www.huiyi8.com/moban/
            afterRender(); 网页模板
     * 简单的抛出异常, 子类可覆盖并提供自己的实现
     * @param cause
     *            接收到的异常
     * @return Throwable 经检查后的异
    protected Throwable launderThrowable(Throwable cause) {
        return new Throwable(cause);*
     * 渲染结束动作, 默认无操作, 子类可覆盖并提供自己的实现
    protected void afterRender() {
        // do nothing
     * 交由子类决定如何构造线程池
     * 
     * @return ExecutorService 线程池
     */
    protected abstract ExecutorService createExecutorService();
     * 交由子类决定如何提取图片地址
     * @param source
     *            页面源码
     * @return 图片地址列表
    protected abstract List<String> scanForImagePaths(CharSequence source);
     * 交由子类决定如何下载文字
     * @param source
     *            页面源码
    protected abstract void renderText(CharSequence source);
     * 交由子类决定如何渲染图片
     * 
     * @param data
     *            图片信息
    protected abstract void renderImage(ImageData data);
     * 交由子类决定如何下载图片
     * @param path
     *            路径
     * @return ImageData 图片信息
     */
    protected abstract ImageData downloadImage(String path);


     * 图片基本信息
     * @author lufang
    public static class ImageData {
        private long height;
        private long width;
        private String uri;
 
        public long getHeight() {
            return height;
        public void setHeight(long height) {
            this.height = height;
        public long getWidth() {
            return width;
        public void setWidth(long width) {
        public String getUri() {
            return uri;
        public void setUri(String uri) {
            this.uri = uri;
0 0