任务执行(二)

来源:互联网 发布:出行软件英文怎么说 编辑:程序博客网 时间:2024/06/15 18:29

    一、串行的页面渲染器

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
原创粉丝点击