【问题标题】:REST Api with Multithreading for handling Files in Spring Boot用于在 Spring Boot 中处理文件的多线程 REST Api
【发布时间】:2019-07-20 19:24:50
【问题描述】:

他们有什么办法让我可以利用多线程概念来并行调用执行,并使创建的@RestController 的执行速度更快,它将接受StringList<MultipartFile> 作为请求参数,代码是工作正常。这里的问题是,如果我通过 for 循环一个接一个地解析一个文件。执行所需的时间更多。

下面是控制器

@RequestMapping(value = "/csvUpload", method = RequestMethod.POST)
    public List<String> csvUpload(@RequestParam String parentPkId, @RequestParam List<MultipartFile> file)
            throws IOException {
        log.info("Entered method csvUpload() of DaoController.class");
        List<String> response = new ArrayList<String>();
        String temp = parentPkId.replaceAll("[-+.^:,]", "");
        for (MultipartFile f : file) {
            String resp = uploadService.csvUpload(temp, f);
            response.add(resp);
        }
        return response;
    }

从控制器,我正在调用uploadService.csvUpload() 方法,我在使用 For 循环时一个接一个地解析文件。

下面是我的 UploadService 类

public String csvUpload(String parentPkId, MultipartFile file) {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(file.getInputStream()));
            String line = "";
            int header = 0;
            while ((line = br.readLine()) != null) {
                // TO SKIP HEADER
                if(header == 0) {
                    header++;  
                    continue;
                }
                header++;
                //Use Comma As Separator
                String[] csvDataSet = line.split(",");
                //Saving it to DB

        }catch(IOException ex) {
            ex.printStackTrace();
        }
        return "Successfully Uploaded "+ file.getOriginalFilename();
    }

如何使这个控制器成为一个多线程的,以便处理是并行和快速的。我是多线程新手,我尝试使用Callable 接口,但Call() 方法不会接受参数。

欢迎任何线索和建议,在此先感谢。

【问题讨论】:

  • 不确定但@Async 注解可能会解决您的问题
  • @SHAHAKASH 任何代码位都会帮助我,如果你能提供的话

标签: java multithreading spring-boot threadpool


【解决方案1】:

您需要创建一个类,该类将实现如下可调用并将期货存储在列表中,最后按如下方式处理期货

public class ProcessMutlipartFile implements Callable<String>
{
   private Mutlipartfile file; 
   private String temp;
   private UploadService uploadService;
   public ProcessMutlipartFile(Mutlipartfile file,String temp, UploadService uploadService )
   {
       this.file=file;
       this.temp=temp,
       this.uploadService=uploadService;
   }

   public String call() throws Exception 
   {

    return   uploadService.csvUpload(temp, file);
    }

 }

在你的控制器中创建一个未来对象列表

 ExecutorService executor = Executors.newFixedThreadPool(10)
List< Future<String> > futureList = new ArrayList<Future<String>>();
     .
     .
     .
         for (MultipartFile f : file) {
                    futureList.add(executor.submit(new ProcessMutlipartFile(file ,temp,uploadService));
                }

终于在你的控制器中

 for (Future f :futureList)
 {
  response.add(f.get());
  }

//shuttingdown the Executor
executor.shutdown();

希望对你有帮助

【讨论】:

    【解决方案2】:

    您可以使用parallel stream执行上传代码

        List<String> response = file.parallelStream().map(f -> uploadService.csvUpload(temp, f))
        .collect(Collectors.toList());
    

    您可以串行或并行执行流。当流并行执行时,Java 运行时会将流划分为多个子流。聚合操作迭代并并行处理这些子流,然后组合结果。

    【讨论】:

      猜你喜欢
      • 2019-08-26
      • 2018-12-04
      • 2022-01-09
      • 2018-01-16
      • 2017-07-22
      • 2018-10-08
      • 1970-01-01
      • 1970-01-01
      • 2018-02-28
      相关资源
      最近更新 更多