天天看點

Java并發程式設計

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> p_w_picpathPaths = scanForImagePaths(source);

        Callable<List<ImageData>> task = new Callable<List<ImageData>>() {

            public List<ImageData> call() {

                List<ImageData> result = new ArrayList<ImageData>();

                for (String path : p_w_picpathPaths)

                    result.add(downloadImage(path));

                return result;

        Future<List<ImageData>> future = executor.submit(task);

        renderText(source);

        try {

            List<ImageData> p_w_picpathData = future.get();

            for (ImageData data : p_w_picpathData)

                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();

     * 交由子類決定如何提取圖檔位址

     * @return 圖檔位址清單

    protected abstract List<String> scanForImagePaths(CharSequence 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;