java 多线程-for-join框架


for-join框架主要是用来支持执行计算密集型任务的,比如图像、视频处理等
其工作原理是:
我们将大的复杂的计算任务划分为无数的小任务(我看了下源码,所有的小任务都被放在了一个队列里面),最后将各个小任务的处理结果整合返回(递归思想)
,如果有多余的处理器的话,这些小任务可以并行运算。
下面我们来看一个例子:在一个大的int数组(存放的值为 0-100的随机数),我们将计算数组中数值大于
50的元素个数。


1 首先新建一个继承 RecursiveTask抽象类的Counter类,这个类的思想是
如果本次任务处理的数字大于某个指定的值(下面类中的size),则继续将这个任务划分为子任务,直到子任务处理的数组大小 小于指定值再处理

public class Counter extends RecursiveTask{

	private int[] values;//被计算的数组
	private int from;//起始值
	private int to;//结束值
	private Predicate p;//定义的 大于50的赛选规则
	private int size;//单词计算(x小任务处理的数组大小)

	public Counter(int[] values,int from,int to,Predicate p,int size){
		this.values = values;
		this.from = from;
		this.to = to;
		this.p = p;
		this.size = size;
	}

	@Override
	protected Integer compute() {
		int count = 0;
		if(to - from < size){//本次任务将处理的数组大小 如果小于指定值则处理数据
			for(int i = from;i < to;i++){
				if(p.test(values[i])){
					count ++;
				}
			}
			return count;
		}else{//本次任务将处理的数组大小 如果大于指定值则将任务分为两个小任务
			int mind = (to + from)/2;
			Counter c1 = new Counter(values, from, mind, p, size);
			Counter c2 = new Counter(values, mind, to, p, size);
			invokeAll(c1,c2);
			return c1.join()+c2.join();
		}
	}
}


2 新建一个测试类

public class Test{
	public static void main(String[] arg){
		int SIZE = 100000000;
		Random r = new Random();
		int[] values = new int[SIZE+1];
		for(int i = 0; i < SIZE; i++){//遍历向数组中添加数据
			values[i] = r.nextInt(100);
		}

		long curent = System.currentTimeMillis();
		Counter c = new Counter(values, 0, SIZE, e->e>50,1000);
		ForkJoinPool pool = new ForkJoinPool();
		pool.invoke(c);
		//输出本次计算大于50的元素个数
		System.out.println(c.join());
		//输出fork-join框架的计算用时
		System.out.println(System.currentTimeMillis() - curent);

		
		long curent2 = System.currentTimeMillis();
		int count = 0;
		for(int i = 0 ; i50){
				count++;
			}
		}
		//输出本次计算小于50的元素个数
		System.out.println(count);
		//输出普通遍历比较计算用时
		System.out.println(System.currentTimeMillis() - curent);
	}
}

输出结果:
48991268
148
48991268
224
由测试结果可以知道:采用fork-join框架计算用时 少于传统的遍历计算用时



你可能感兴趣的:(JAVA)