Fork/Join实例

(1)含返回值

           问题:1+2+...+100

          1.思路

             分解为1+2,3+4,,...99+100,然后对这50个结果进行求和

          2.任务实现

import java.util.concurrent.ExecutionException;
import java.util.concurrent.RecursiveTask;

public class CalculateTask extends RecursiveTask<Integer>{//因为需要返回值,所以使用RecursiveTask
	private static final long serialVersionUID = -8486729149866588744L;

	private static final int THRESHOLD = 2;// 阈值
	
	private int start;
	
	private int end;
	
	public CalculateTask(int start, int end) {
        this.start = start;
        this.end = end;
    }
	
	@Override
	protected Integer compute() {
		int sum = 0;
		if (end-start<THRESHOLD) {//分解为2个数的和然后计算
			for(;start<=end;start++){
				sum += start;
			}
		}else {
			int mid = (start + end) >>> 1;
		    RecursiveTask<Integer> task1 = new CalculateTask(start, mid);
		    RecursiveTask<Integer> task2 = new CalculateTask(mid+1, end);
		    invokeAll(task1,task2);
		    
		    try {
				sum = task1.get()+task2.get();
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
		}
		
		return sum;
	}
}

          3.测试

package com.test;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;

import org.junit.Test;

public class QuickSortTest {

	@Test
	public void test(){
		ForkJoinPool forkJoinPool = new ForkJoinPool();
		
		// 生成一个计算任务,负责计算1+2+3+4
		CalculateTask task = new CalculateTask(1, 4);
		// 执行一个任务
		Future<Integer> result = forkJoinPool.submit(task);
		forkJoinPool.shutdown();
		try {
			System.out.println(result.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
	}
}

(2)无返回值

           问题:快排

          1.思路

             根据中间值分解为2个区间,然后区间内再执行

          2.任务实现

import java.util.concurrent.RecursiveAction;

public class CalculateTask extends RecursiveAction{//这里不需要返回值,所以使用RecursiveAction
	private static final long serialVersionUID = 2476846494375574971L;

	private int[] number = {};
	
	private int begin;
	
	private int end;
	
	private static final int THRESHOLD = 1;// 阈值
	
	public QuickSortTask(int[] number,int begin, int end){
		this.number = number;
		this.begin = begin;
		this.end = end;
	}
	
	@Override
	protected void compute() {
		if (end-begin<THRESHOLD) {//只有一个数,那么不用排序了
			return;
		}else{
			int mid = adjust(number,begin,end);
			
			QuickSortTask task1 = new QuickSortTask(number,begin, mid - 1);
			QuickSortTask task2 = new QuickSortTask(number,mid + 1, end);
			
			invokeAll(task1, task2);
		}
	}

	private int adjust(int[] a, int begin, int end) {
		int flag = a[begin];
		
		while (begin<end) {
			while (a[end]>=flag && begin<end) 
				end--;
			if (begin<end) 
				a[begin] = a[end];
			
			while (a[begin]<=flag && begin<end) 
				begin++;
			if (begin<end)
				a[end] = a[begin];
		}
		a[begin] = flag;
		
		return begin;
	}
}
          3.测试

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.junit.Test;

public class QuickSortTest {

	@Test
	public void test() {
		ForkJoinPool forkJoinPool = new ForkJoinPool();

		int[] a = {54,12,36,16,96,62};

		QuickSortTask task = new QuickSortTask(a,0, 5);
		// 执行一个任务
		forkJoinPool.submit(task);
		while(!task.isDone()){
	        }

		for (int i : a) {
			System.out.print(i+" ");
		}
		forkJoinPool.shutdown();
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
# jdk7新特性 ## try-with-resources 是一种声明了`一种或多种资源的try语句`。资源是指在程序用完了之后必须要关闭的对象。try-with-resources语句保证了每个声明了的`资源在语句结束的时候都会被关闭`。任何实现了java.lang.`AutoCloseable`接口的对象,和实现了java .io .`Closeable`接口的对象,`都可以当做资源使用`。 ``` try ( InputStream is = new FileInputStream("xx"); OutputStream os = new FileOutputStream("xx") ) { //xxx //不用关闭了,JVM帮你关闭流 ``` ## 多异常统一处理 在Java 7中,catch代码块得到了升级,用以在`单个catch块中处理多个异常`。如果你要捕获多个异常并且它们包含相似的代码,使用这一特性将会减少代码重复度。 ``` try { //xxx } catch (AException | BException e) { e.printStackTrace(); } ``` 缺点是异常处理细粒度降低 ## 泛型推导 ``` List list = new ArrayList(); ``` `泛型实例`的创建可以通过`类型推断`来简化,`可以去掉`后面new部分的泛型类型,`只用`就可以了。 ## 使用ForkJoin Java 7开始引入了一种新的Fork/Join线程池,它可以执行一种特殊的任务:把一个大任务拆成多个小任务并行执行。 我们举个例子:如果要计算一个超大数组的和,最简单的做法是用一个循环在一个线程内完成: ```ascii ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐ └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘ ``` 还有一种方法,可以把数组拆成两部分,分别计算,最后加起来就是最终结果,这样可以用两个线程并行执行: ```ascii ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐ └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘ ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐ └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘ ``` 如果拆成两部分还是很大,我们还可以继续拆,用4个线程并行执行: ```ascii ┌─┬─┬─┬─┬─┬─┐ └─┴─┴─┴─┴─┴─┘ ┌─┬─┬─┬─┬─┬─┐ └─┴─┴─┴─┴─┴─┘ ┌─┬─┬─┬─┬─┬─┐ └─┴─┴─┴─┴─┴─┘ ┌─┬─┬─┬─┬─┬─┐ └─┴─┴─┴─┴─┴─┘ ``` 这就是Fork/Join任务的原理:判断一个任务是否足够小,如果是,直接计算,否则,就分拆成几个小任务分别计算。这个过程可以反复“裂变”成一系列小任务。 我们来看如何使用Fork/Join对大数据进行并行求和: ``` public class Main { public static void main(String[] args) throws Exception { // 创建2000个随机数组成的数组: long[] array = new long[2000]; long expectedSum = 0; for (int i = 0; i < array.length; i++) { array[i] = random(); expectedSum += array[i]; } System.out.println("Expected sum: " + expectedSum); // fork/join: ForkJoinTask task = new SumTask(array, 0, array.length); long startTime = System.currentTimeMillis(); Long result = ForkJoinPool.commonPool().invoke(task); long endTime = System.currentTimeMillis(); System.out.println("Fork

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值