递归多线程实现前缀和

    这是一年前在上多核并行计算的时候老师留的作业。现在重新看java多线程,又把老师的ppt拿出来来看。发现还是讲的不错的。今天又花了两个小时实现了一遍。

    贴两张ppt的介绍。

    题目为:

Given  int[]input,produceint[]output whereoutput[i] is the sum input[0]+input[1]+…+input[i]


上面是顺序的做法,如何用多线程去做?


第二步


根节点的fromleft等于0

左侧的fromleft等于父节点的fromleft

右侧的fromleft等于父节点的fromleft加上左侧节点的sum

Fromleft相当于每个节点要补上的值。从上到下,最后到最底层,获得每个节点的最终结果。


     java实现的代码如下。因为分了两步,所以搞了两个继承Thread的类。

package prefixsum;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class PrefixSum {
	// map存数组存的是地址, 不能直接把int[]放进去!
	// 为了省事,就把map设置为了public
	public static Map<String, ArrayList<Integer>> map = new HashMap<String, ArrayList<Integer>>();
	public static void main(String[] args) {
		MyThread thread1 = new MyThread(0, 8);
		thread1.run();
		SecondGo second = new SecondGo(0, 8, 0);
		second.run();
		System.out.println(thread1.sum);
		System.out.println(map);
		
		for (int k = 0; k < 8; k++) {
			System.out.print((map.get(k + "," + (k + 1)).get(1) + map.get(k + "," + (k + 1)).get(0)) + ";");
		}
	}
}

// 第一次
class MyThread extends Thread {
	public int[] input = {6, 4, 16, 10, 16, 14, 2, 8};
	public int sum;
	private int[] range = new int[2];
	public MyThread(int a, int b) {
		range[0] = a;
		range[1] = b;
	}
	public void run() {
		ArrayList<Integer> list = new ArrayList<Integer>();
		if (range[1] - range[0] == 1) {
			sum = input[range[0]];
		}
		else {
			MyThread left = new MyThread(range[0], 
					(range[0] + range[1])/2);
			MyThread right = new MyThread((range[0] + range[1])/2,
					range[1]);
			left.start();
			right.run();
			try {
				left.join();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			sum = left.sum + right.sum;
		}
		list.add(sum);
		PrefixSum.map.put(range[0] + "," + range[1], list);
	}
}

// 第二次
class SecondGo extends Thread {
	private int[] range = new int[2];
	private int fromleft;
	public SecondGo(int a, int b, int c) {
		range[0] = a;
		range[1] = b;
		fromleft = c;
	};
	public void run() {
		if (range[1] - range[0] == 1) {
				ArrayList<Integer> arr = PrefixSum.map.get(range[0] + "," + range[1]);
				arr.add(fromleft);
				return;
		}
		else {
			ArrayList<Integer> arr = PrefixSum.map.get(range[0] + "," + range[1]);
			arr.add(fromleft);
			String b = range[0] + "," + (range[0] + range[1])/2;
			// 算右边节点的fromleft,等于左孩子的sum加上自己的leftsum
			int temp = (Integer)fromleft + PrefixSum.map.get(b).get(0); 
			SecondGo left = new SecondGo(range[0], (range[0] + range[1])/2, fromleft);
			SecondGo right = new SecondGo((range[0] + range[1])/2, range[1], temp);
			left.start();
			right.run();
			try {
				left.join();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值