http://blog.csdn.net/a352193394/article/details/39872923

2014-10-07 23:55 4818人阅读 评论(0) 收藏 举报
 分类:
多线程(22) 

版权声明:本文为博主原创文章,未经博主允许不得转载。

 

目录(?)[+]

 

在Java7中,JDK提供对多线程开发提供了一个非常强大的框架,就是Fork/Join框架。这个是对原来的Executors更

进一步,在原来的基础上增加了并行分治计算中的一种Work-stealing策略,就是指的是。当一个线程正在等待他创建的

子线程运行的时候,当前线程如果完成了自己的任务后,就会寻找还没有被运行的任务并且运行他们,这样就是和

Executors这个方式最大的区别,更加有效的使用了线程的资源和功能。所以非常推荐使用Fork/Join框架。

下面我们以一个例子来说明这个框架如何使用,主要就是创建一个含有10000个资源的List,分别去修改他的内容。

  1. package com.bird.concursey.charpet8;
  2. /**
  3. * store the name and price of a product
  4. * @author bird 2014年10月7日 下午11:23:14
  5. */
  6. public class Product {
  7. private String name;
  8. private double price;
  9. public String getName() {
  10. return name;
  11. }
  12. public void setName(String name) {
  13. this.name = name;
  14. }
  15. public double getPrice() {
  16. return price;
  17. }
  18. public void setPrice(double price) {
  19. this.price = price;
  20. }
  21. }
  1. package com.bird.concursey.charpet8;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. /**
  5. * generate a list of random products
  6. * @author bird
  7. * 2014年10月7日 下午11:24:47
  8. */
  9. public class ProductListGenerator {
  10. public List<Product> generate(int size) {
  11. List<Product> list = new ArrayList<Product>();
  12. for(int i = 0 ; i < size; i++) {
  13. Product product = new Product();
  14. product.setName("Product" + i);
  15. product.setPrice(10);
  16. list.add(product);
  17. }
  18. return list;
  19. }
  20. }
  1. package com.bird.concursey.charpet8;
  2. import java.util.List;
  3. import java.util.concurrent.ForkJoinPool;
  4. import java.util.concurrent.RecursiveAction;
  5. import java.util.concurrent.TimeUnit;
  6. public class Task extends RecursiveAction {
  7. private static final long serialVersionUID = 1L;
  8. // These attributes will determine the block of products this task has to
  9. // process.
  10. private List<Product> products;
  11. private int first;
  12. private int last;
  13. // store the increment of the price of the products
  14. private double increment;
  15. public Task(List<Product> products, int first, int last, double increment) {
  16. super();
  17. this.products = products;
  18. this.first = first;
  19. this.last = last;
  20. this.increment = increment;
  21. }
  22. /**
  23. * If the difference between the last and first attributes is greater than
  24. * or equal to 10, create two new Task objects, one to process the first
  25. * half of products and the other to process the second half and execute
  26. * them in ForkJoinPool using the invokeAll() method.
  27. */
  28. @Override
  29. protected void compute() {
  30. if (last - first < 10) {
  31. updatePrices();
  32. } else {
  33. int middle = (first + last) / 2;
  34. System.out.printf("Task: Pending tasks:%s\n", getQueuedTaskCount());
  35. Task t1 = new Task(products, first, middle + 1, increment);
  36. Task t2 = new Task(products, middle + 1, last, increment);
  37. invokeAll(t1, t2);
  38. }
  39. }
  40. private void updatePrices() {
  41. for (int i = first; i < last; i++) {
  42. Product product = products.get(i);
  43. product.setPrice(product.getPrice() * (1 + increment));
  44. }
  45. }
  46. public static void main(String[] args) {
  47. ProductListGenerator productListGenerator = new ProductListGenerator();
  48. List<Product> products = productListGenerator.generate(10000);
  49. Task task = new Task(products, 0, products.size(), 0.2);
  50. ForkJoinPool pool = new ForkJoinPool();
  51. pool.execute(task);
  52. do {
  53. System.out.printf("Main: Thread Count: %d\n",
  54. pool.getActiveThreadCount());
  55. System.out.printf("Main: Thread Steal: %d\n", pool.getStealCount());
  56. System.out.printf("Main: Parallelism: %d\n", pool.getParallelism());
  57. try {
  58. TimeUnit.MILLISECONDS.sleep(5);
  59. } catch (InterruptedException e) {
  60. e.printStackTrace();
  61. }
  62. } while (!task.isDone());
  63. pool.shutdown();
  64. if(task.isCompletedNormally()) {
  65. System.out.printf("Main: The process has completed normally.\n");
  66. }
  67. for(Product product : products) {
  68. if(product.getPrice() != 12) {
  69. System.out.printf("Product %s: %f\n",product.getName(),product.getPrice());
  70. }
  71. }
  72. System.out.println("Main: End of the program.\n");
  73. }
  74. }

In this example, you have created a ForkJoinPool object and a subclass of the
ForkJoinTask class that you execute in the pool. To create the ForkJoinPool object,
you have used the constructor without arguments, so it will be executed with its default
configuration. It creates a pool with a number of threads equal to the number of processors
of the computer. When the ForkJoinPool object is created, those threads are created and
they wait in the pool until some tasks arrive for their execution.

Since the Task class doesn't return a result, it extends the RecursiveAction class. In the
recipe, you have used the recommended structure for the implementation of the task. If the
task has to update more than 10 products, it divides those set of elements into two blocks,
creates two tasks, and assigns a block to each task. You have used the first and last
attributes in the Task class to know the range of positions that this task has to update in the
list of products. You have used the first and last attributes to use only one copy of the
products list and not create different lists for each task.

To execute the subtasks that a task creates, it calls the invokeAll() method. This is a
synchronous call, and the task waits for the finalization of the subtasks before continuing
(potentially finishing) its execution. While the task is waiting for its subtasks, the worker thread
that was executing it takes another task that was waiting for execution and executes it. With
this behavior, the Fork/Join framework offers a more efficient task management than the
Runnable and Callable objects themselves.

 
The invokeAll() method of the ForkJoinTask class is one of the main differences
between the Executor and the Fork/Join framework. In the Executor framework, all the tasks
have to be sent to the executor, while in this case, the tasks include methods to execute and
control the tasks inside the pool. You have used the invokeAll() method in the Task class,
that extends the RecursiveAction class that extends the ForkJoinTask class.
You have sent a unique task to the pool to update all the list of products using the execute()
method. In this case, it's an asynchronous call, and the main thread continues its execution.
You have used some methods of the ForkJoinPool class to check the status and the
evolution of the tasks that are running. The class includes more methods that can be useful
for this purpose. See the Monitoring a Fork/Join pool recipe for a complete list of
those methods.
Finally, like with the Executor framework, you should finish ForkJoinPool using the
shutdown() method.
 
 
 

使用Java7提供的Fork/Join框架的更多相关文章

  1. Java 7 Fork/Join 框架

    在 Java7引入的诸多新特性中,Fork/Join 框架无疑是重要的一项.JSR166旨在标准化一个实质上可扩展的框架,以将并行计算的通用工具类组织成一个类似java.util中Collection ...

  2. Java开发笔记(一百零六)Fork+Join框架实现分而治之

    前面依次介绍了普通线程池和定时器线程池的用法,这两种线程池有个共同点,就是线程池的内部线程之间并无什么关联,然而某些情况下的各线程间存在着前因后果关系.譬如人口普查工作,大家都知道我国总人口为14亿左 ...

  3. 使用Java7提供Fork/Join框架

    在Java7在.JDK它提供了多线程开发提供了一个非常强大的框架.这是Fork/Join框架.这是原来的Executors更多 进一步,在原来的基础上添加了并行分治计算中的一种Work-stealin ...

  4. Java7任务并行执行神器:Fork&Join框架

    Fork/Join是什么? Fork/Join框架是Java7提供的并行执行任务框架,思想是将大任务分解成小任务,然后小任务又可以继续分解,然后每个小任务分别计算出结果再合并起来,最后将汇总的结果作为 ...

  5. Java7任务并行执行神器:Fork&Join框架

    原 Java7任务并行执行神器:Fork&Join框架 2018年01月12日 17:25:03 Java技术栈 阅读数:426 标签: JAVAFORKJOIN 更多 个人分类: Java ...

  6. 聊聊并发(八)——Fork/Join框架介绍

      作者 方腾飞 发布于 2013年12月23日 | 被首富的“一个亿”刷屏?不如定个小目标,先把握住QCon上海的优惠吧!2 讨论 分享到:微博微信FacebookTwitter有道云笔记邮件分享 ...

  7. 转:聊聊并发(八)——Fork/Join框架介绍

    1. 什么是Fork/Join框架 Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架. 我们再通过 ...

  8. Java并发编程--Fork/Join框架使用

    上篇博客我们介绍了通过CyclicBarrier使线程同步,可是上述方法存在一个问题,那就是假设一个大任务跑了2个线程去完毕.假设线程2耗时比线程1多2倍.线程1完毕后必须等待线程2完毕.等待的过程线 ...

  9. 多线程(五) Fork/Join框架介绍及实例讲解

    什么是Fork/Join框架 Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架. 我们再通过For ...

随机推荐

  1. angular中的jsonp记录

    angular的正常机制采用引入$http服务的形式进行 get post等的访问.但是在跨域访问的时候就需要采用jsonp了. 不废话,直接上示例和引用原文地址: 比如访问地址为 http://ur ...

  2. Mr.Jobs

    Mr.Jobs   by xue 最近的情绪很down,情商智商一直往下降 主要的原因是工作不好找.不是我的要求太高, 而是公司的HR都很不要. 当然首先得自我检讨,但是,damn,这种事情我怎么做的 ...

  3. Java参数传递问题

    参考资料:http://blog.sina.com.cn/s/blog_59ca2c2a0100qhjx.html   http://blog.csdn.net/a412588063/article/ ...

  4. iframe标签flash遮盖页面元素问题——wmode参数

    最近做项目过程中,遇到各种小问题,所以打算通过博客园来记录各问题的解决办法. 这篇的问题背景是这样子的:项目是用的AngularJS框架,在某个页面上用了wangEditor富文本编辑器插件(gith ...

  5. zoj 2750 Idiomatic Phrases Game

    迪杰斯特拉单源最短路算法.对成语进行预处理.做出邻接矩阵即可. #include<cstdio> #include<cstring> #include<cmath> ...

  6. peepingtom

    简介 辅助评判网页渗透价值的自动化工具.它可以对制定IP和指定端口的所有http(s)服务进行快照,以一种易于浏览阅读的方式展示出来. 安装 git clone https://bitbucket.o ...

  7. iOS开发富文本

    NSMutableAttributedString * attributedStr = [[NSMutableAttributedString alloc] initWithString:@" ...

  8. apache 安装[转]

    Apache简介         Apache HTTP Server(简称Apache)是Apache软件基金会的一个开放源码的网页服务器,可以在大多数计算机操作系统中运行,由于其多平台和安全性被广 ...

  9. mysql解决中文乱码问题

    安装文件 my.ini default-character-set=gbk 安装文件 db.opt default-character-set=gbkdefault-collation=gbk_chi ...

  10. 设计模式 单例模式(Singleton) [ 转载 ]

    设计模式 单例模式(Singleton) [ 转载 ] 转载请注明出处:http://cantellow.iteye.com/blog/838473 前言 懒汉:调用时才创建对象 饿汉:类初始化时就创 ...