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

进一步,在原来的基础上添加了并行分治计算中的一种Work-stealing策略。就是指的是。

当一个线程正在等待他创建的

子线程执行的时候,当前线程假设完毕了自己的任务后,就会寻找还没有被执行的任务而且执行他们,这样就是和

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

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

package com.bird.concursey.charpet8;

/**
* store the name and price of a product
* @author bird 2014年10月7日 下午11:23:14
*/
public class Product { private String name;
private double price; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public double getPrice() {
return price;
} public void setPrice(double price) {
this.price = price;
} }

package com.bird.concursey.charpet8;

import java.util.ArrayList;
import java.util.List; /**
* generate a list of random products
* @author bird
* 2014年10月7日 下午11:24:47
*/
public class ProductListGenerator { public List<Product> generate(int size) {
List<Product> list = new ArrayList<Product>();
for(int i = 0 ; i < size; i++) {
Product product = new Product();
product.setName("Product" + i);
product.setPrice(10);
list.add(product);
}
return list;
}
}

package com.bird.concursey.charpet8;

import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.TimeUnit; public class Task extends RecursiveAction { private static final long serialVersionUID = 1L;
// These attributes will determine the block of products this task has to
// process.
private List<Product> products;
private int first;
private int last;
// store the increment of the price of the products
private double increment; public Task(List<Product> products, int first, int last, double increment) {
super();
this.products = products;
this.first = first;
this.last = last;
this.increment = increment;
} /**
* If the difference between the last and first attributes is greater than
* or equal to 10, create two new Task objects, one to process the first
* half of products and the other to process the second half and execute
* them in ForkJoinPool using the invokeAll() method.
*/
@Override
protected void compute() {
if (last - first < 10) {
updatePrices();
} else {
int middle = (first + last) / 2;
System.out.printf("Task: Pending tasks:%s\n", getQueuedTaskCount());
Task t1 = new Task(products, first, middle + 1, increment);
Task t2 = new Task(products, middle + 1, last, increment);
invokeAll(t1, t2);
}
} private void updatePrices() {
for (int i = first; i < last; i++) {
Product product = products.get(i);
product.setPrice(product.getPrice() * (1 + increment));
}
} public static void main(String[] args) {
ProductListGenerator productListGenerator = new ProductListGenerator();
List<Product> products = productListGenerator.generate(10000);
Task task = new Task(products, 0, products.size(), 0.2); ForkJoinPool pool = new ForkJoinPool();
pool.execute(task); do {
System.out.printf("Main: Thread Count: %d\n",
pool.getActiveThreadCount());
System.out.printf("Main: Thread Steal: %d\n", pool.getStealCount());
System.out.printf("Main: Parallelism: %d\n", pool.getParallelism());
try {
TimeUnit.MILLISECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (!task.isDone()); pool.shutdown(); if(task.isCompletedNormally()) {
System.out.printf("Main: The process has completed normally.\n");
} for(Product product : products) {
if(product.getPrice() != 12) {
System.out.printf("Product %s: %f\n",product.getName(),product.getPrice());
}
} System.out.println("Main: End of the program.\n");
} }

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 Fork/Join 框架

    简介 从JDK1.7开始,Java提供Fork/Join框架用于并行执行任务,它的思想就是讲一个大任务分割成若干小任务,最终汇总每个小任务的结果得到这个大任务的结果. 这种思想和MapReduce很像 ...

  2. Java并发编程(07):Fork/Join框架机制详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.Fork/Join框架 Java提供Fork/Join框架用于并行执行任务,核心的思想就是将一个大任务切分成多个小任务,然后汇总每个小任务 ...

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

    http://blog.csdn.net/a352193394/article/details/39872923 使用Java7提供的Fork/Join框架 2014-10-07 23:55 4818 ...

  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. Java 7 Fork/Join 框架

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

随机推荐

  1. 异常:未能载入文件或程序集”DAL”或它的某一个依赖项——解决的方法

    以下是我再使用抽象工厂+反射重构机房时,在Factoy中出现了以下一个问题: 去网上查了一下资料,发现这是一个非常普遍的问题,它出现的原因主要有两种: 第一种: 载入DLL路径错误.解决的方法是调整D ...

  2. android ADT 设置编辑字体

    新配置的android ADT 设置编辑字体的时候  可能里面没有我们想要的Courier new 这种舒服的字体 那么就在 字体选项窗口的  做下端 有个显示更多字体的链接  然后就显示微软的所有字 ...

  3. PHP - 表单与验证

    第11章 表单与验证 学习要点: 1.Header()函数 2.接收及验证数据 我们对Web感兴趣,认为它有用的原因是其主要通过基于HTML的表单发布和收集信息的能力.这些表单用来鼓励网站的反馈.进行 ...

  4. 编译kernel:编译

    韦东山Linux视频第1期_裸板_UBoot_文件系统_驱动初步第10课第3节 内核启动流程分析之Makefile.WMV  1. 编译内核分三步: make xxx_defconfig [linux ...

  5. 在Qt中如何使用QtDesigner创建的UI文件

    使用Qt有一些时间了,一直在IDE环境(qtcreator和VS2003+集成器)中使用,自然少了很多麻烦的步骤.但是在享受这种便利的同 时,我们也失去了理解更多知识背后的点滴.在IDE中,如果我们要 ...

  6. 好消息:8月25日广州嵌入式Linux开发免费项目约定你

    8月18日,粤嵌深圳分校举行了盛大的免费嵌入式项目体验,众多嵌入式爱好者排队参加项目体验的火爆场景仿佛还在眼前,体验效果得到学员一致好评.时隔一周,粤嵌广州总部也不容落后,在粤嵌广州总部举办<嵌 ...

  7. jquery-easyui实现页面布局和增删改查操作(SSH2框架支持)转载

    http://blessht.iteye.com/blog/1069749/ 已注册:ooip 关联的csdn 前几天心血来潮用jquery-easyui+spring.struts2.hiberna ...

  8. 史上最全的java随机数/字符串生成算法(转)

    代码如下: package com.zuidaima.core.util; import java.util.Random; public class RandomUtil { public stat ...

  9. Eclipse完美汉化教程

    首先我们打开http://www.eclipse.org/babel/downloads.php下载语言包. 方法一:可以复制图片里的地址通过Eclipse下载,Help→Install New So ...

  10. Swift - 使用ALAssetsLibrary获取相簿里所有图片,视频(附样例)

    1,ALAssetsLibrary介绍 (1)通过创建ALAssetsLibrary的实例可以访问系统Photos里的图片与视频.这里图片不仅包括相机拍摄的照片,还包括从iTunes导入的和从其他设备 ...