Future接口和Callable接口的使用

  1. import  java.util.ArrayList;  
  2. import  java.util.List;  
  3. import  java.util.concurrent.Callable;  
  4. import  java.util.concurrent.ExecutionException;  
  5. import  java.util.concurrent.ExecutorService;  
  6. import  java.util.concurrent.Executors;  
  7. import  java.util.concurrent.Future;  
  8. import  java.util.concurrent.FutureTask;  
  9.   
  10. public   class  ConcurrentCalculator {  
  11.   
  12.     private  ExecutorService exec;  
  13.     private   int  cpuCoreNumber;  
  14.     private  List<Future<Long>> tasks =  new  ArrayList<Future<Long>>();  
  15.   
  16.     // 内部类   
  17.     class  SumCalculator  implements  Callable<Long> {  //线程中用来计算的部分,相当于run()方法   
  18.         private   int [] numbers;  
  19.         private   int  start;  
  20.         private   int  end;  
  21.   
  22.         public  SumCalculator( final   int [] numbers,  int  start,  int  end) {  
  23.             this .numbers = numbers;  
  24.             this .start = start;  
  25.             this .end = end;  
  26.         }  
  27.   
  28.         public  Long call()  throws  Exception {  
  29.             Long sum = 0l;  
  30.             for  ( int  i = start; i < end; i++) {  
  31.                 sum += numbers[i];  
  32.             }  
  33.             return  sum;  
  34.         }  
  35.     }  
  36.   
  37.     public  ConcurrentCalculator() {  
  38.         cpuCoreNumber = Runtime.getRuntime().availableProcessors();  
  39.         exec = Executors.newFixedThreadPool(cpuCoreNumber);  
  40.     }  
  41.   
  42.     public  Long sum( final   int [] numbers) {  
  43.         // 根据CPU核心个数拆分任务,创建FutureTask并提交到Executor   
  44.         for  ( int  i =  0 ; i < cpuCoreNumber; i++) {  
  45.             int  increment = numbers.length / cpuCoreNumber +  1 ;  
  46.             int  start = increment * i;  
  47.             int  end = increment * i + increment;  
  48.             if  (end > numbers.length)  
  49.                 end = numbers.length;  
  50.             SumCalculator subCalc = new  SumCalculator(numbers, start, end);  
  51.             FutureTask<Long> task = new  FutureTask<Long>(subCalc);  //线程   
  52.             tasks.add(task);  
  53.             if  (!exec.isShutdown()) {  
  54.                 exec.submit(task);        //执行线程   
  55.             }  
  56.         }  
  57.         return  getResult();  
  58.     }  
  59.   
  60.     /**  
  61.      * 迭代每个只任务,获得部分和,相加返回  
  62.      *  
  63.      * @return  
  64.      */   
  65.     public  Long getResult() {  
  66.         Long result = 0l;  
  67.         for  (Future<Long> task : tasks) {  
  68.             try  {  
  69.                 // 如果计算未完成则阻塞   
  70.                 Long subSum = task.get();   //得到每个线程的计算结果   
  71.                 result += subSum;  
  72.             } catch  (InterruptedException e) {  
  73.                 e.printStackTrace();  
  74.             } catch  (ExecutionException e) {  
  75.                 e.printStackTrace();  
  76.             }  
  77.         }  
  78.         return  result;  
  79.     }  
  80.   
  81.     public   void  close() {  
  82.         exec.shutdown();  
  83.     }  
  84.   
  85.     public   static   void  main(String[] args)  
  86.     {  
  87.         int [] numbers =  new   int [] {  1 ,  2 ,  3 ,  4 ,  5 ,  6 ,  7 ,  8 ,  10 ,  11  };  
  88.         ConcurrentCalculator calc = new  ConcurrentCalculator();  
  89.         Long sum = calc.sum(numbers);  
  90.         System.out.println(sum);  
  91.         calc.close();    
  92.   
  93.     }  
  94. }  
 

猜你喜欢

转载自kfcman.iteye.com/blog/2108180
今日推荐