XML Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
package com.lyzx.restdy.callable;
import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /** * 关于多线程的一道面试题 * 对于一个大数组求和(为模拟真实的情况没加一次等待20ms), * 要求使用多线程实现 * 大致思路是把一个大数组分开,每个线程值计算其中一部分的和 * 最后把结果合并 * / public class T { public static void main(String[] args) { //数组长度 int itemCount =2000; int[] arr = new int[itemCount]; for(int i=0;i <itemCount;i++){ arr[i]=i; } //线程数,使用线程池管理线程 int threadCount = 10; ExecutorService es = Executors.newFixedThreadPool(threadCount); //使用计数器阻塞主线程,等待所有的数组求和完毕后放开主线程 CountDownLatch latch = new CountDownLatch(threadCount); //分配每个线程计算一部分数组最后求和 int perItem=itemCount /threadCount; Future <String>[] allFuture = new Future[perItem]; for(int i=0;i <threadCount;i++){ Future <String> f = es.submit(new Z(arr,i*perItem,perItem*(i+1),latch)); allFuture[i]=f; } es.shutdown(); int finalCount = 0; for(int i=0;i <threadCount;i++){ try { String value = allFuture[i].get(); finalCount += Integer.parseInt(value); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } //阻塞主线程等待计算数组和的线程执行完毕 try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(finalCount); } } class Z implements Callable <String>{ //[start,end) private int start =-1; private int end =-1; private int[] arr; private int count = 0; private CountDownLatch latch ; public Z(int[] arr,int start,int end,CountDownLatch latch){ if(arr == null || start <0 || end <= 0 || start > end || latch == null){ throw new RuntimeException( "param is Error"); } this.arr = arr; this.start=start; this.end=end; this.latch = latch; } /** * 对于arr数组的start到end项累加 * / @Override public String call() throws Exception { for(int i=start;i <end;i++){ //每相加一次就等待20毫秒,没有实际意义,只为了模拟实际的生成环境,可能出现的阻塞情况 Thread.sleep(20); count += i; } latch.countDown(); return String.valueOf(count); } } |