任务执行(二)

    一、串行的页面渲染器

class SingleThreadRenderer {
	void renderPage(CharSequence source) {
		renderText(source);
		List<ImageData> imageData = new ArrayList<ImageData>();
		for(ImageInfo imageInfo : scanForImageInfo(source)) {
			imageData.add(imageInfo.downloadImage());
		}
		for(ImageData data : imageData) {
			renderImage(data);
		}
	}
}


    二、为了使页面渲染器实现更高的并发性,首先将渲染过程分解为两个任务,一个是渲染所有的文本,

另一个是下载所有的图像。

    Callable和Future有助于表示协同任务之间的交互。下面的代码中创建了一个Callable来下载所有的图像,

并将其提交到一个ExecutorService这将返回一个描述任务执行情况的Future。当主任务需要图像时,它会

等待Future.get的调用结果。如果幸运的话,当开始请求时所有的图像就已经下载完成了,即使没有,至少

图像的下载任务也已经提交开始了。


    使用Future等待图像下载

class FutureRenderer {
	private final ExecutorService executor = .;
	
	void renderPage(CharSequence source) {
		final List<ImageInfo> imageInfos = scanForImageInfo(source);
		Callable<List<ImageData>> task = new Callable<List<ImageData>> () {
			public List<ImageData> call() {
				List<ImageData> result = new ArrayList<ImageData>();
				for(ImageInfo imageInfo : imageInfos) {
					result.add(imageInfo.downloadImage());
				}
				return result;
			}
		};
		
		Future<List<ImageData>> future = executor.submit(task);
		renderText(source);
		try{
			List<ImageData> imageData = future.get();
			for(ImageData data : imageData) {
				rederImage(data);
			}
		} catch (InterruptedException e) {
			//重新设置线程的中断状态
			Thread.currentThread().interrupt();
			//由于不需要结束,因此取消任务
			future.cancel(true);
		} catch (ExecutionException e) {
			throw launderThrowable(e.getCause());
		}
	}
}


    三、使用CompletionService实现页面渲染器

    可以通过CompletionService从两个方法来提高页面渲染器的性能:缩短总运行时间以及提高响应性。为每一幅

图像的下载都创建一个独立任务,并在线程池中执行它们,从而将串行的下载过程转换为并行的过程:这将减少

下载所有图像的总时间。此外,通过从CompletionService中获取结果以及使每张图片在下载完成后立刻显示出来,

能使用户获得一个更加动态和更高响应性的用户界面。

class Renderer {
	private final ExecutorService executor;
	
	Renderer(ExecutorService executor) {
		this.executor = executor;
	}
	
	void renderPage(CharSequence source ) {
		List<ImageInfo> info = scanForImageInfo(source);
		CompletionService<ImageData> completionService = new ExecutorCompletionService<ImageData>(executor);
		
		for(final ImageInfo imageInfo : info) {
			completionService.submit(new Callable<ImageData>() {
				public ImageData call() {
					return imageInfo.downloadImage();
				}
			});
		}
		
		renderText(source);
		
		try{
			for(int t = 0, n = info.size(); t < n; t++) {
				Future<ImageData> f = completionService.take();
				ImageData imageData = f.get();
				renderImage(imageData);
			}
		} catch (InterruptedException e) {
			Thread.currentThread().interrupt();
		} catch (ExecutionException e) {
			throw launderThrowable(e.getCause());
		}
	}
}


通过Future来取消任务

public static void timedRun(Runnable r,long timeout,TimeUnit unit) throws InterruptedException {
	Future<?> task = taskExec.submit(r);
	try{
		task.get(timeout, unit);
	} catch(TimeoutException e) {
		//接下来任务将被取消
	} catch(ExecutionException e) {
		throw launderThrowable(e.getCause());
	} finally {
		task.cancel(true);//如果任务正在运行,将被中断
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值