使用Fork/Join实现WordCount例子

Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。
Fork/Join框架是一个比较特殊的线程池框架,专用于需要将一个任务不断分解成子任务(分叉),再不断进行汇总得到最终结果(结合)的计算过程。
比起传统的线程池类ThreadPoolExecutor,ForkJoinPool 实现了工作窃取算法,使得空闲线程能够主动分担从别的线程分解出来的子任务,
从而让所有的线程都尽可能处于饱满的工作状态,提高执行效率。

下面将演示一个使用Fork/Join实现WordCount例子,假设有一个目录,里面都是文本文件,现在要统计这些所有的文件里面的字符串的个数

package com.fork;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.RecursiveTask;

/**
 * RecursiveTask 表示有返回值的计算
 */
public class FileRecursiveTask extends RecursiveTask<Map<String, Integer>> {

	private static final long serialVersionUID = 1L;
	private final List<String> contents;
	
	public FileRecursiveTask(File file) {
		System.out.println("处理文件:" + file.getAbsolutePath());
		try {
			contents = Files.readAllLines(Paths.get(file.toURI()));
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 业务逻辑处理,相当于map
	 */
	protected Map<String, Integer> compute() {
		Map<String, Integer> map = new HashMap<>();
		for(String content : contents){
			String[] strs = content.split(" ");
			for(String str : strs){
				if(map.containsKey(str)){
					int val = map.get(str);
					map.put(str, val+1);
				} else {
					map.put(str, 1);
				}
			}
		}
		return map;
	}
}
package com.fork;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 * 每个文件会使用一个线程去处理,最终汇总到一起
 */
public class ForkRecursiveTask extends RecursiveTask<Map<String, Integer>> {

	private static final long serialVersionUID = 1L;
	private final File[] files;
	
	public ForkRecursiveTask(String path) {
		files = new File(path).listFiles();
	}
	
	/**
	 * 汇总处理,相当于reduce
	 */
	protected Map<String, Integer> compute() {
		List<ForkJoinTask<Map<String, Integer>>> tasks = new ArrayList<>();
		for(File file : files){
			FileRecursiveTask frt = new FileRecursiveTask(file);
			tasks.add(frt.fork());
		}
		
		Map<String, Integer> result = new HashMap<>();
		for(ForkJoinTask<Map<String, Integer>> task : tasks){
			Map<String, Integer> map = task.join();
			for(String key : map.keySet()){
				if(result.containsKey(key)){
					result.put(key, result.get(key) + map.get(key));
				} else {
					result.put(key, map.get(key));
				}
			}
		}
		return result;
	}
}
package com.fork;

import java.util.Map;
import java.util.concurrent.ForkJoinPool;

public class ForkJoinPoolTest {
	public static void main(String[] args) {
		ForkJoinPool forkJoinPool = new ForkJoinPool();
		Map<String, Integer> map = forkJoinPool.invoke(new ForkRecursiveTask("e:/txts"));
		//输出最终所有的计算结果
		for(String key : map.keySet()){
			System.out.println(key + "=" + map.get(key));
		}
	}
}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值