`

Java并行编程–从并行任务集获取反馈

 
阅读更多

Java并行编程–从并行任务集获取反馈


在并行任务启动后,强制性地从并行任务得到反馈。

假想有一个程序,可以发送批邮件,还使用了多线程机制。你想知道有多少邮件成功发送吗?你想知道在实际发送过程期间,这个批处理工作的实时进展吗?

要实现多线程的这种反馈,我们可以使用Callable接口。此接口的工作方式基本上与Runnable相同,但是执行方法(call())会返回一个值,该值反映了执行计算的结果。

package com.ricardozuasti;

import java.util.concurrent.Callable;

public class FictionalEmailSender implements Callable<Boolean>{
	private String to;
	private String subject;
	private String body;
	public FictionalEmailSender(String to, String subject, String body){
		this.to = to;
		this.subject = subject;
		this.body = body;
	}

	@Override
	public Boolean call() throws InterruptedException {
		// 在0~0.5秒间模拟发送邮件
		Thread.sleep(Math.round(Math.random()*0.5*1000));
		// 假设我们有80%的几率成功发送邮件
		if(Math.random()>0.2){
			return true;
		}else{
			return false;
		}
	}
	
}

注意:Callable接口可用于返回任意数据类型,因此我们的任务可以返回我们需要的任何信息。

现在,我们使用一个线程池ExecutorService来发送邮件,由于我们的任务是以Callable接口实现的,我们提交执行的每个新任务,都会得到一个Future引用。注意我们要使用直接的构造器创建ExecutorService,而不是使用来自Executors的工具方法创建。这是因为使用指定类ThreadPoolExecutor提供了一些方法可以派上用场。

package com.ricardozuasti;

import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.ArrayList;
import java.util.List;

public class Concurrency2 {
	public static void main(String[] args){
		try{
			ThreadPoolExecutor executor = new ThreadPoolExecutor(30, 30, 1,
     TimeUnit.SECONDS, new LinkedBlockingQueue());
			List<Future<Boolean>> futures = new ArrayList<Future<Boolean>>(9000);
			// 发送垃圾邮件, 用户名假设为4位数字
			for(int i=1000; i<10000; i++){
				futures.add(executor.submit(new FictionalEmailSender(i+"@sina.com",
						"Knock, knock, Neo", "The Matrix has you...")));
			}
			// 提交所有的任务后,关闭executor
			System.out.println("Starting shutdown...");
			executor.shutdown();
			
			// 每秒钟打印执行进度
			while(!executor.isTerminated()){
				executor.awaitTermination(1, TimeUnit.SECONDS);
				int progress = Math.round((executor.getCompletedTaskCount()
*100)/executor.getTaskCount());
				System.out.println(progress + "% done (" + 
executor.getCompletedTaskCount() + " emails have been sent).");
			}
			// 现在所有邮件已发送完, 检查futures, 看成功发送的邮件有多少
			int errorCount = 0;
			int successCount = 0;
			for(Future<Boolean> future : futures){
				if(future.get()){
					successCount++;
				}else{
					errorCount++;
				}
			}
			System.out.println(successCount + " emails were successfully sent, but " +
					errorCount + " failed.");
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
}

执行这个类,输出结果如下:

Starting shutdown...
1% done (118 emails have been sent).
2% done (232 emails have been sent).
3% done (358 emails have been sent).
5% done (478 emails have been sent).
6% done (587 emails have been sent).
7% done (718 emails have been sent).
9% done (850 emails have been sent).
10% done (969 emails have been sent).
……

所有的任务都由ExecutorService提交,我们开始它的关闭(防止提交新任务)并使用一个循环(实时场景,可能你会继续做其它的事情)来等待,直至所有任务都被执行完成、计算和打印当前每次迭代的进度。

注意,你可以存储executor引用,也可以在任意时间从其它线程查询它的计算结果和报告进程进度。

最后,使用Future集合引用,我们得到ExecutorService提交的每个Callable接口,通知成功发送的邮件数量和发送失败的邮件数量。

此结构不但易于使用,还使得相关性得到清晰的隔离,在调度程序和实际任务之间提供了一个预定义的通信机制。




分享到:
评论

相关推荐

    java 并行编程

    java的并行编程的样例,jdk1.7中并行框架的样例,多种并行的实现方法

    JAVA并行计算的一些资料 论文

    JAVA并行计算的一些资料 论文JAVA并行计算的一些资料 论文JAVA并行计算的一些资料 论文JAVA并行计算的一些资料 论文

    java并行编程(Java Concurrency in Practice) 英文版chm

    &lt;&lt;java并行编程&gt;&gt;英文版chm格式,英文名称&lt;Java Concurrency in Practice&gt;,一直想买这本书,但总是缺货,找到了电子版,分享给大家。 Java Concurrency in Practice By Brian Goetz, Tim Peierls, Joshua Bloch,...

    Java共享内存并行编程

    Java共享内存并行编程----------别下了 想删除删不掉(群众反映不是很好)

    Java并发编程实战

    6.3.4 在异构任务并行化中存在的局限 6.3.5 CompletionService:Executor与BlockingQueue 6.3.6 示例:使用CompletionService实现页面渲染器 6.3.7 为任务设置时限 6.3.8 示例:旅行预定门户网站 第7章 取消与...

    JAVA并发编程实践 .pdf

    如何识别可并行执行的任务,如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步...

    并行编程会像当年的Java一样流行.pdf

    并行编程会像当年的Java一样流行

    Java并发编程实践 PDF 高清版

    本书的读者是那些具有一定Java编程经验的程序员、希望了解Java SE 5,6在线程技术上的改进和新特性的程序员,以及Java和并发编程的爱好者。 目录 代码清单 序 第1章 介绍 1.1 并发的(非常)简短历史 1.2 线程的...

    Java并发编程实战.rar

    《Java并发编程实战》是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则,如何将小的线程...

    JAVA并发编程实战_标签.pdf

    《Java并发编程实战》是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则,如何将小的线程...

    Java并发编程学习笔记

    目前,在Java并发编程方面论述系统、内容详实的中文资料很少。本文是作者在实际工作中经验总结,部分内容来自《Java Concurrency In Practice》。...读完前八章即可应付一般的 Java 多线程编程任务。

    基于JAVA的并行程序编辑器研究与设计

    并行编程在高性能计算领域的应用越来越广泛。国家863计划项目“网格服务环境结点建设及其支撑技术研究”的子课题 “用户开发环境研究”,旨在开发出以客户端/服务器模式运行的,能在远程编辑、编译、运行、调试并行...

    并行编程库(Coursera):Java并行编程(https:www.coursera.orglearnparallel-programming-in-java)

    并行编程Coursera Java并行编程( )

    java并发编程

    本书全面介绍了如何使用Java 2平台进行并发编程,较上一版新增和扩展的内容包括:, ·存储模型 ·取消 ·可移植的并行编程 ·实现并发控制的工具类, Java平台提供了一套广泛而功能强大的api,工具和技术。...

    Java 并发编程实战

    6.3.4 在异构任务并行化中存在的局限 6.3.5 CompletionService:Executor与BlockingQueue 6.3.6 示例:使用CompletionService实现页面渲染器 6.3.7 为任务设置时限 6.3.8 示例:旅行预定门户网站 第7章 取消与...

    Java优化编程(第2版)

    Java优化编程(第2版)通过丰富、完整、富有代表性的实例,展示了如何提升Java应用性能,并且给出了优化前与优化后的Java应用程序的性能差别,以实际的实例与数字告诉你,为什么不可以这么做,应该怎么做,深入分析...

    Java并发编程ppt.rar

    java并发编程

    Java并发编程实践

    如何识别可并行执行的任务,如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的...

    java并发编程实战相关书籍

    如何识别可并行执行的任务,如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的...

    Java并发编程实战(华章专业开发者书库).mobi

    如何识别可并行执行的任务,如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的...

Global site tag (gtag.js) - Google Analytics