`

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

 
阅读更多

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

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

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

  1. package com.ricardozuasti;  
  2.  
  3. import java.util.concurrent.Callable;  
  4.  
  5. public class FictionalEmailSender implements Callable<Boolean>{  
  6.     private String to;  
  7.     private String subject;  
  8.     private String body;  
  9.     public FictionalEmailSender(String to, String subject, String body){  
  10.         this.to = to;  
  11.         this.subject = subject;  
  12.         this.body = body;  
  13.     }  
  14.  
  15.     @Override 
  16.     public Boolean call() throws InterruptedException {  
  17.         // 在0~0.5秒间模拟发送邮件  
  18.         Thread.sleep(Math.round(Math.random()*0.5*1000));  
  19.         // 假设我们有80%的几率成功发送邮件  
  20.         if(Math.random()>0.2){  
  21.             return true;  
  22.         }else{  
  23.             return false;  
  24.         }  
  25.     }  
  26.       
  27. }  

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

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

  1. package com.ricardozuasti;  
  2.  
  3. import java.util.concurrent.Future;  
  4. import java.util.concurrent.LinkedBlockingQueue;  
  5. import java.util.concurrent.ThreadPoolExecutor;  
  6. import java.util.concurrent.TimeUnit;  
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9.  
  10. public class Concurrency2 {  
  11.     public static void main(String[] args){  
  12.         try{  
  13.             ThreadPoolExecutor executor = new ThreadPoolExecutor(30301,  
  14.      TimeUnit.SECONDS, new LinkedBlockingQueue());  
  15.             List<Future<Boolean>> futures = new ArrayList<Future<Boolean>>(9000);  
  16.             // 发送垃圾邮件, 用户名假设为4位数字  
  17.             for(int i=1000; i<10000; i++){  
  18.                 futures.add(executor.submit(new FictionalEmailSender(i+"@sina.com",  
  19.                         "Knock, knock, Neo""The Matrix has you...")));  
  20.             }  
  21.             // 提交所有的任务后,关闭executor  
  22.             System.out.println("Starting shutdown...");  
  23.             executor.shutdown();  
  24.               
  25.             // 每秒钟打印执行进度  
  26.             while(!executor.isTerminated()){  
  27.                 executor.awaitTermination(1, TimeUnit.SECONDS);  
  28.                 int progress = Math.round((executor.getCompletedTaskCount()  
  29. *100)/executor.getTaskCount());  
  30.                 System.out.println(progress + "% done (" +   
  31. executor.getCompletedTaskCount() + " emails have been sent).");  
  32.             }  
  33.             // 现在所有邮件已发送完, 检查futures, 看成功发送的邮件有多少  
  34.             int errorCount = 0;  
  35.             int successCount = 0;  
  36.             for(Future<Boolean> future : futures){  
  37.                 if(future.get()){  
  38.                     successCount++;  
  39.                 }else{  
  40.                     errorCount++;  
  41.                 }  
  42.             }  
  43.             System.out.println(successCount + " emails were successfully sent, but " +  
  44.                     errorCount + " failed.");  
  45.         }catch(Exception ex){  
  46.             ex.printStackTrace();  
  47.         }  
  48.     }  
  49. }  

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

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

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

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

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

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

原文链接:http://blog.csdn.net/chszs/article/details/7418880

分享到:
评论

相关推荐

    java 并行编程

    这个压缩包文件"javaenhance"很可能包含了与Java并行编程相关的示例代码和教程,旨在帮助我们理解并掌握这些概念和技术。 在Java中,实现并行编程主要依靠以下几个关键组件和概念: 1. **线程**:Java中的线程是...

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

    综上所述,Java并行计算涵盖了从基础的多线程到高级的分布式计算框架,开发者可以通过这些工具和概念,设计和实现高效的并行程序,处理大规模的数据和计算任务。这些论文和资料应该会深入探讨这些主题,并可能包含...

    Java并发编程:设计原则与模式(Concurrent.Programming.in.Java)(中英版)

    《Java并发编程:设计原则与模式》是一本深入探讨Java多线程编程的权威书籍,由Doug Lea撰写,第二版全面涵盖了Java并发处理的各个方面。这本书不仅提供了丰富的理论知识,还介绍了实战中的设计原则和模式,对于Java...

    基于Web的Java并行计算

    通过将任务分解并在全球范围内分散到数千甚至数万台计算机上执行,研究人员成功地加快了解密过程的速度,展示了基于Web的Java并行计算的巨大潜力。 #### 结论 综上所述,基于Web的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共享内存并行编程 #### 1. 引言 随着计算机技术的发展,特别是多核处理器的普及,高效利用多核架构成为提高程序性能的关键因素之一。Java作为一种跨平台的语言,不仅在Web开发、企业级应用等领域有着广泛...

    java并发编程实战源码,java并发编程实战pdf,Java

    《Java并发编程实战》是Java并发编程领域的一本经典著作,它深入浅出地介绍了如何在Java平台上进行高效的多线程编程。这本书的源码提供了丰富的示例,可以帮助读者更好地理解书中的理论知识并将其应用到实际项目中。...

    并行编程模型与语言.pptx

    - Java 的 Fork/Join 框架和 Python 的 concurrent.futures 模块是常见的任务并行编程工具。 - **流水线并行模型**: - 计算任务被划分为多个阶段,并允许不同阶段之间的并行执行。 - Valgrind 和 IntelTBB 是...

    Java 并发编程实战.pdf

    根据提供的信息,“Java 并发编程实战.pdf”这本书聚焦于Java并发编程的实践与应用,旨在帮助读者深入了解并掌握Java中的多线程技术及其在实际项目中的应用技巧。虽然部分内容未能提供具体章节或实例,但从标题及...

    [并行计算——结构·算法·编程]

    - 并行编程语言:如C++、Java、Python的并行库,以及专门的并行语言如Charm++、HPF等。 - 错误处理与调试:在并行环境中,由于并发性和不确定性,错误检测和调试更为复杂。 5. **并行计算应用**: - 大数据分析...

    Java并发编程实践源码

    《Java并发编程实践》是一本深入探讨Java多线程与并发编程的经典著作,其源码提供了丰富的示例,帮助读者理解和应用并发编程的核心概念。在这些文件中,我们可以看到多种并发设计模式和策略的实际运用,下面将逐一...

    JAVA并发编程艺术pdf版

    《JAVA并发编程艺术》是Java开发者深入理解和掌握并发编程的一本重要著作,它涵盖了Java并发领域的核心概念和技术。这本书详细阐述了如何在多线程环境下有效地编写高效、可靠的代码,对于提升Java程序员的技能水平...

    java8并行计算示例--可动态配置

    并行计算是一种编程范式,它将大型任务分解为多个小任务,这些小任务可以在不同的处理器核心上同时运行,以缩短总体的执行时间。在 Java 8 中,通过并行流,开发者可以很容易地利用多核处理器的优势,无需深入理解...

    Java并发编程从入门到精通(pdf)(附源码)

    《Java并发编程从入门到精通》是一本专为Java开发者设计的深度学习并发编程的书籍。作者韩剑锋,凭借其12年的IT行业经验,曾担任多家IT公司的研发总监和技术总监,以其丰富的实战经验和深厚的理论知识,为读者提供了...

    java 并行爬取网页

    【标题】:“Java 并行爬取网页” 在Java编程中,实现并行爬取网页是一种...通过以上技术,Java并行爬虫可以高效地处理大规模的网页抓取任务,特别是在处理大量单词翻译时,其并行处理能力能显著提升程序的运行效率。

    Java-Java函数式编程教程

    Java函数式编程是一种编程范式,它强调使用函数作为程序的基本构建块,将计算视为函数的组合,并且尽可能避免改变状态和可变数据。在Java 8及更高版本中,函数式编程得到了官方的大力支持,引入了Lambda表达式、...

    Java网络编程(第4版)PDF

    Java提供的Thread类和Runnable接口是实现多线程的关键,通过它们可以创建并行运行的任务,提高程序的响应速度和效率。同时,还会探讨线程同步和通信的机制,如synchronized关键字、wait/notify机制以及高级的并发...

    Java并发编程实践.pdf

    在Java并发编程中,首先需要理解“并发”(Concurrency)和“并行”(Parallelism)的区别。“并发”指的是多个任务在同一时间段内交替执行,而“并行”则指的是多个任务同时执行。在实际应用中,“并发”更侧重于...

    并行编程语言:X10.zip

    史上最全编程语言全套教程,共99门编程语言,包括: 函数式编程语言 ...并行编程语言 数据分析编程语言 数据库查询语言 系统编程语言 脚本编程语言 逻辑编程语言 面向对象编程语言 等所有常见的变成语言系列教程

    并行编程语言:Elixir.zip

    史上最全编程语言全套教程,共99门编程语言,包括: 函数式编程语言 ...并行编程语言 数据分析编程语言 数据库查询语言 系统编程语言 脚本编程语言 逻辑编程语言 面向对象编程语言 等所有常见的变成语言系列教程

Global site tag (gtag.js) - Google Analytics