REST Api 使用多线程处理 Spring 引导中的文件
REST Api with Multithreading for handling Files in Spring Boot
他们有什么办法让我可以利用多线程概念并行调用执行并使创建的 @RestController
的执行速度更快,它将接受 String
和 List<MultipartFile>
作为请求参数,并且代码正在运行 fine.Problem 这里是如果我通过 for 循环一个接一个地解析一个文件。执行所花费的时间更多。
Below is Controller
@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 循环时一个接一个地解析文件。
下面是我的上传服务Class
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();
}
How to make this Controller as a Multithreaded so that processing is parallel and fast. I'm new to Multithreading and I tried by making use of Callable
interface but the Call()
method will not take parameters.
欢迎任何线索和建议,在此先感谢。
您需要创建一个 Class,它将实现如下所示的可调用并将期货存储在列表中,最后按如下方式处理期货
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();
希望这对您有所帮助
您可以使用parallel stream
执行上传代码
List<String> response = file.parallelStream().map(f -> uploadService.csvUpload(temp, f))
.collect(Collectors.toList());
You can execute streams in serial or in parallel. When a stream executes in parallel, the Java runtime partitions the stream into multiple substreams. Aggregate operations iterate over and process these substreams in parallel and then combine the results.
他们有什么办法让我可以利用多线程概念并行调用执行并使创建的 @RestController
的执行速度更快,它将接受 String
和 List<MultipartFile>
作为请求参数,并且代码正在运行 fine.Problem 这里是如果我通过 for 循环一个接一个地解析一个文件。执行所花费的时间更多。
Below is Controller
@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 循环时一个接一个地解析文件。
下面是我的上传服务Class
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();
}
How to make this Controller as a Multithreaded so that processing is parallel and fast. I'm new to Multithreading and I tried by making use of
Callable
interface but theCall()
method will not take parameters.
欢迎任何线索和建议,在此先感谢。
您需要创建一个 Class,它将实现如下所示的可调用并将期货存储在列表中,最后按如下方式处理期货
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();
希望这对您有所帮助
您可以使用parallel stream
执行上传代码 List<String> response = file.parallelStream().map(f -> uploadService.csvUpload(temp, f))
.collect(Collectors.toList());
You can execute streams in serial or in parallel. When a stream executes in parallel, the Java runtime partitions the stream into multiple substreams. Aggregate operations iterate over and process these substreams in parallel and then combine the results.