4.2 ForkJoin_拆分任务
来源:互联网 发布:简单的平面设计软件 编辑:程序博客网 时间:2024/06/05 21:08
ForkJoin 拆分任务
概述
本章节用一个简单示例说明如何拆分任务。示例是更新一批产品的价格。任务类继承ForkJoinTask类,并复写execute方法,在execute方法中进行任务拆分或者价格更新。如果任务需要更新的产品数量大于10,它将拆分这些元素为两部分,并相应创建两个任务,再通过调用invokeAll方法来分配所拆分的任务,invokeAll方法是一个同步调用,这个任务将等待子任务完成,然后继续执行。当一个主任务等待它的子任务时,执行这个主任务的工作者线程接受另一个等待执行的任务并开始执行。正因为这个行为,Fork/Join框架提供了比Runnable和Callable更加高效的任务管理机制。ForkJoinTask类的invokeALl方法是执行器框架和Fork/Join框架的主要差异之一。在执行器框架中,所有的任务必须发送给执行器;反而,在下面的示例中,线程池包含了待执行方法的任务,也包含了任务的控制。
ForkJoinPool也需要通过shutdown方法来关闭。
示例代码如下:
public class ForkDemo { public static void main(String[] args){ //生成产品数据 System.out.println("main:生成产品数据"); List<Product> products = new ArrayList<Product>(10000); for(int i=0; i<10000; i++){ Product p = new Product(); p.setPrice(10); products.add(p); } //创建TaskDemo对象来更新产品价格 TaskDemo task = new TaskDemo(products,0,products.size()); //创建ForkJoinPool对象,并启动 System.out.println("main:创建ForkJoinPool对象,并启动"); ForkJoinPool pool = new ForkJoinPool(); pool.execute(task); System.out.println("main:输出线程池信息"); do{ System.out.println("main:线程数量:" + pool.getActiveThreadCount()); System.out.println("main:偷窃数量:" + pool.getStealCount()); System.out.println("main:并行级别:" + pool.getParallelism()); try { TimeUnit.MICROSECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } }while(!task.isDone()); //关闭线程池 System.out.println("main:关闭线程池"); pool.shutdown(); if(task.isCompletedNormally()){ System.out.println("main:任务处理完成"); } System.out.println("main:退出"); }}class Product { private double price; public double getPrice() { return price; } public void setPrice(double price) { this.price = price; }}/** * 采用分治算法对产品价格进行调整 * * 如果一次计算的元素个数大于10,则继续拆分;否则进行产品价格更新 */class TaskDemo extends RecursiveAction{ private List<Product> products; private int first; private int last; TaskDemo(List<Product> products, int first, int last) { this.products = products; this.first = first; this.last = last; } @Override protected void compute() { if(last-first < 10){ //如果小于10个元素,则更新价格 updatePrice(); }else{ //如果大于10个元素,则进行拆分 int middle = (last+first)/2; TaskDemo t1 = new TaskDemo(products,first,middle+1); TaskDemo t2 = new TaskDemo(products,middle+1,last); invokeAll(t1,t2); } } /** 更新价格为20 **/ private void updatePrice(){ for(int i=first;i<last; i++){ products.get(i).setPrice(20); } }}
程序运行日志:
main:生成产品数据main:创建ForkJoinPool对象,并启动main:输出线程池信息main:线程数量:1main:偷窃数量:0main:并行级别:2main:线程数量:2main:偷窃数量:2main:并行级别:2main:关闭线程池main:任务处理完成main:退出
0 0
- 4.2 ForkJoin_拆分任务
- 4.3 ForkJoin_聚合任务结果
- java大任务拆分
- Grunt如何拆分Gruntfile.js进行任务拆分的?
- MindMapper中的任务怎样进行拆分
- python 简单任务拆分多线程框架
- 拆分
- 智能停车诱导系统--大数据部分--任务拆分
- 将复杂的大任务拆分成多个简单的小任务进行计算
- 利用FutureTask和ExecutorService实现一个任务拆分成多个任务,实现性能提高
- 利用FutureTask和ExecutorService实现一个任务拆分成多个任务,实现性能提高
- 游戏任务成就体系的实现(二):业务拆分和大功能模块定位
- Map拆分List拆分
- 数据库拆分:横向拆分和纵向拆分
- 数据库拆分:横向拆分和纵向拆分
- 拆分字段
- 拆分字符串
- 拆分框架
- 1001. 害死人不偿命的(3n+1)猜想 (15)
- iOS下的Notification的使用
- server at localhost was unable to start within 45 seconds的解决办法
- poj 2251 Dungeon Master
- LeetCode Insert Interval
- 4.2 ForkJoin_拆分任务
- Listener实践
- 河北拓睿网络科技有限公司
- 青岛城乡客运一体化 市区校车智能系统加强
- nrpe
- mybatis入门学习
- leetcode 75 Combinations
- iOS7: 那些容易被忽视的新特性
- java对list集合分组