请检查如下代码,如有问题,请正确指出!(java、多线程)

 
package com.test.thread;

import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.*;
// 业务上想实现 从文件中获取数据,每100个数据启动一个线程,若最后不足100的也起一个线程,每个线程分别处理各自的源数据。
public class Test {
   private static ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
   public void execute() {
      long startTime = System.currentTimeMillis();
      System.out.println(" ------------   execute task  execute !   -------------------   "+startTime);
      List<Integer> recordIds = Lists.newArrayList();
      int threadNum = 1;
      String fileName = "../data.txt";
      File file = new File(fileName);
      BufferedReader reader = null;
      CompletionService<String> service = new ExecutorCompletionService<String>(executor);
      int line = 1;
      try {
         System.out.println("以行为单位读取文件内容,一次读一整行:");
         reader = new BufferedReader(new FileReader(file));
         String tempString = null;

         // 一次读入一行,直到读入null为文件结束
         while ((tempString = reader.readLine()) != null) {
            // 显示行号
            System.out.println("line " + line + ": " + tempString);
            Integer recordId = Integer.valueOf(tempString.trim());
            recordIds.add(recordId);
            if(recordIds.size()%100==0){
               service.submit(new ThreadTask(recordIds,String.valueOf(threadNum)));
               recordIds.clear();
               threadNum++;
            }
         }
         if(recordIds.size()>0){
            service.submit(new ThreadTask(recordIds,String.valueOf(threadNum)));
         }

         for (int i = 1; i <= threadNum; i++) {
            try {
               Future<String> future = service.take();
               String result = future.get();
               System.out.println(" --------------- 线程执行完成结果  :-------------------  "+result);
            } catch (Exception e) {
               e.printStackTrace();
            }
         }
         reader.close();
      } catch (IOException e) {
         e.printStackTrace();
      } finally {
         if (reader != null) {
            try {
               reader.close();
            } catch (IOException e1) {
            }
         }
      }


      long endTime = System.currentTimeMillis();
      System.out.println(" ------------   execute task  execute !   -------------------   "+(endTime-startTime)/1000+" 秒!");
   }


   class ThreadTask implements Callable<String> {

      private List<Integer> recordIds;
      private String  name;

      public ThreadTask(List<Integer> recordIds,String name) {
         this.recordIds = recordIds;
         this.name = name;
      }

      @Override
      public String call() throws Exception {
         long startTime = System.currentTimeMillis();
         if (CollectionUtils.isEmpty(recordIds)) {
            return null;
         }
         System.out.println(name +"  , recordIds.size():  " +recordIds.size()+" ------------   thread  is start execute !   ----------   "+startTime);
         // ... 任务处理
         long endTime = System.currentTimeMillis();
         System.out.println(name + " ------------   thread  is end  execute ! ------------   "+endTime+ "---------- 共耗时: "+(endTime-startTime)/1000+" 秒! ");
         return name+ " success!";
      }
   }
}
提示:代码的整个流程没有问题,启用线程池,从文件中获取源数据,每100个启动一个新线程处理,问题在于,其
recordIds.clear();
recordIds是传递给每个任务线程的源数据集合,recordIds是引用类型,所以,多线程共享了源数据,简单的解决方案是:将上面的clear()删除,替换为:recordIds = Lists.newArrayList(); 最后一个需要注意的是,如果线程池如果不再使用了,需要进行关闭,executor.shutdown();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值