这是一年前在上多核并行计算的时候老师留的作业。现在重新看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();
}
}
}
}