首页 > 解决方案 > 处理对 Spring Rest Controller 的同时 HTTP 调用

问题描述

我正在尝试从客户端同时接收对此控制器的调用。客户端尝试发送单个文件的块,服务器尝试首先在 MultipartFile 数组中收集所有这些块,然后在收到所有块时重新组装。但是,我不知道这段代码是否是线程安全的,因为我有像文件数组这样的共享资源。我在收到第一个块时创建它。我很困惑,因为这段代码以一种有趣的方式运行。例如,它进入 (file == null) 语句 4-5 次。如果有人可以帮助使此代码无状态或线程安全,我将不胜感激!

@PostMapping("/mtupload/chunk")
public ResponseEntity<String> getMultithreadedUpload(@RequestParam("fileName") String fileName,
                                             @RequestParam("fileSize") String fileSize,
                                             @RequestParam("chunkSize") String chunkSize,
                                             @RequestParam("numberOfChunks") String numberOfChunks,
                                             @RequestParam("chunk") MultipartFile chunk,
                                             @RequestParam("chunkId") String chunkId,
                                             @RequestParam("fileId") String fileID) throws IOException {

    int chunkkSize = Integer.parseInt(chunkSize);
    int fileeSize = Integer.parseInt(fileSize);
    int chunkkId = Integer.parseInt(chunkId);
    int numberOfChunkss = Integer.parseInt(numberOfChunks);
    int fileIdd = Integer.parseInt(fileID);

    if(file == null)
    {
        System.out.println("Server created array of length " + numberOfChunkss + " Inside chunk " + chunkId);
        
        //static MultipartFile[] file is defined as global variable
        file = new MultipartFile[numberOfChunkss];
    }
    if(chunk.getSize() == 0)
    {
        return new ResponseEntity<>(" Server failed to get chunk "+ chunkId + " !", HttpStatus.INTERNAL_SERVER_ERROR);
    }

    System.out.println("Server got chunk " + chunkId );

    file[chunkkId] = chunk;
    System.out.println("Chunk size in File " + chunkId  + " : " + file[chunkkId].getSize());

    // call to store the file when all chunks are received.
    //        storageService.storeChunks(file, fileName, numberOfChunkss, chunkkSize);
    return new ResponseEntity<>(" Server got chunk "+ chunkId + " !", HttpStatus.OK);
}

标签: springmultithreadingresthttpsimultaneous

解决方案


代码不是线程安全的。就好像不止一个线程会创建一个新的file. 您可以声明文件 volatile 并将同步添加到空检查块:

if(file==null) {
  synchronized(this) {
    if(file==null) {
    ...
    }
  }
}

假设 chunkid 是唯一的,则生成的代码将是线程安全的。


推荐阅读