两种多线程实现分治法算法

来源:互联网 发布:山海经图鉴软件 编辑:程序博客网 时间:2024/05/22 04:53
利用比较熟悉的Runnable接口实现分治法求解
package Test;import java.util.HashMap;import java.util.Map;import java.util.Random;public class RunnableTest {private int cpuCoreNumber; private Map<SumCalculator,Thread> tasks = new HashMap<SumCalculator,Thread>(); private long sumtotal=0l; // 内部类 class SumCalculator implements Runnable { private int[] numbers; private int start; private int end; private long sum=0l;public SumCalculator(final int[] numbers, int start, int end) {  this.numbers = numbers;      this.start = start;      this.end = end; } public void run() { for (int i = start; i < end; i++) {                 sum += numbers[i];             } System.out.println(sum);        }     }       public RunnableTest() {         cpuCoreNumber = Runtime.getRuntime().availableProcessors();         System.out.println("计算机核心数"+cpuCoreNumber);    }       public long sum(final int[] numbers) throws InterruptedException { 
//分治法求解        for (int i = 0; i < cpuCoreNumber; i++) {             int increment = numbers.length / cpuCoreNumber + 1;             int start = increment * i;              int end = increment * i + increment;             System.out.println(increment+":"+start+":"+end);            if (end > numbers.length)                 end = numbers.length;               SumCalculator subCalc = new SumCalculator(numbers, start, end);                        Thread thread=new Thread(subCalc);            tasks.put(subCalc, thread);            thread.start();        }         return getResult();     }      private long getResult() throws InterruptedException {// TODO Auto-generated method stub for(Map.Entry<SumCalculator, Thread> entry:tasks.entrySet()){ entry.getValue().join();//如果线程死亡进行求解总和 sumtotal+=entry.getKey().sum; } return sumtotal;}public static void main(String[] args) throws InterruptedException {long startTime=System.currentTimeMillis();   //获取开始时间int[] numbers = new int[1000000];for(int i=0;i<numbers.length;i++){numbers[i]=new Random().nextInt(1000000);}RunnableTest calc = new RunnableTest(); System.out.println("总和"+calc.sum(numbers)); long endTime=System.currentTimeMillis(); //获取结束时间System.out.println("程序运行时间: "+(endTime-startTime)+"ms");}}

下面从别的地方看到可以用ExecutorService和Callable接口实现接口实现多线程

package Test;import java.util.ArrayList; import java.util.List; import java.util.Random;import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; public class ExecutorTest {private ExecutorService exec; private int cpuCoreNumber; private List<Future<Long>> tasks = new ArrayList<Future<Long>>();  // 内部类 class SumCalculator implements Callable<Long> { private int[] numbers; private int start; private int end; public SumCalculator(final int[] numbers, int start, int end) {  this.numbers = numbers;      this.start = start;      this.end = end; } public Long call() throws Exception { Long sum = 0l; for (int i = start; i < end; i++) {                 sum += numbers[i];             }             return sum;         }     }       public ExecutorTest() {         cpuCoreNumber = Runtime.getRuntime().availableProcessors();         System.out.println("计算机核心数"+cpuCoreNumber);        exec = Executors.newFixedThreadPool(cpuCoreNumber);     }       public Long sum(final int[] numbers) {         // 根据CPU核心个数拆分任务,创建FutureTask并提交到Executor         for (int i = 0; i < cpuCoreNumber; i++) {             int increment = numbers.length / cpuCoreNumber + 1; //6  6            int start = increment * i; //0 6             int end = increment * i + increment; //6 12            System.out.println(increment+":"+start+":"+end);            if (end > numbers.length)                 end = numbers.length;   //第一次不执行,第二次为10             SumCalculator subCalc = new SumCalculator(numbers, start, end);             FutureTask<Long> task = new FutureTask<Long>(subCalc);             tasks.add(task);             if (!exec.isShutdown()) {                 exec.submit(task);             }         }         return getResult();     }       /**      * 迭代每个只任务,获得部分和,相加返回      *       * @return      */    public Long getResult() {         Long result = 0l;         for (Future<Long> task : tasks) {             try {                 // 如果计算未完成则阻塞                 Long subSum = task.get();                 result += subSum;             } catch (InterruptedException e) {                 e.printStackTrace();             } catch (ExecutionException e) {                 e.printStackTrace();             }         }         return result;     }       public void close() {         exec.shutdown();     } public static void main(String[] args) {long startTime=System.currentTimeMillis();   //获取开始时间int[] numbers = new int[10];for(int i=0;i<numbers.length;i++){numbers[i]=new Random().nextInt(1000000);}ExecutorTest calc = new ExecutorTest(); Long sum = calc.sum(numbers); System.out.println(sum); calc.close();long endTime=System.currentTimeMillis(); //获取结束时间System.out.println("程序运行时间: "+(endTime-startTime)+"ms");}}


0 0