当前位置: 首页 > news >正文

Callable Future 实现多线程按照顺序上传文件

  /**
   * 异步上传 BiopsyFlow 中的所有视频和音频文件到暂存服务器
   */
  private List<String> uploadBiopsyFlowFiles(BiopsyFlow biopsyFlow, SyncFile SyncFile) {

    List<String> fileBase64List = syncFile.getFileBase64List();
    if (CollectionUtils.isEmpty(syncFile.getFileBase64List())) {
      log.info("没有文件需要上传");
      return Collections.emptyList();
    }

    log.info("上传文件数量:{}", fileBase64List.size());
    List<Callable<String>> tasks = new ArrayList<>();
    for (String file : fileBase64List) {
      Callable<String> task = () -> {
        log.debug("上传线程:{}", Thread.currentThread().getName());
        try {
          return fileDealUtils.uploadTxFile(file, biopsyFlow.getTransId());
        } catch (Exception e) {
          log.error("文件上传失败, 异常={}", e.getMessage());
          return null;
        }
      };
      tasks.add(task);
    }

    // 使用公共线程池提交任务
    List<Future<String>> futures = new ArrayList<>();
    try {
      for (Callable<String> task : tasks) {
        Future<String> future = pullVideoTaskExecutor.submit(task);
        futures.add(future);
      }

      // 按顺序获取结果
      List<String> fileIds = new ArrayList<>();
      for (Future<String> future : futures) {
        try {
          String fileId = future.get();
          if (fileId != null) {
            fileIds.add(fileId);
          } else {
            log.error("文件上传失败: 返回的文件ID为空");
            return Collections.emptyList();
          }
        } catch (Exception e) {
          log.error("文件上传失败: 异常={}", e.getMessage());
          return Collections.emptyList();
        }
      }

//     // TODO 测试下载,上线之前删除
//      for (String fileId : fileIds) {
//        String base64 = fileDealUtils.testDownMp4(fileId);
//        log.info("下载的文件id:{}, 对应下载的视频base64:{}",  fileId,base64.substring(0,100));
//      }

      return fileIds;
    } catch (Exception e) {
      log.error("任务执行过程中发生异常", e);
      return Collections.emptyList();
    }
  }

http://www.dtcms.com/a/162429.html

相关文章:

  • 知识付费平台推荐及对比介绍
  • 更新日期自动填充
  • ESG跨境电商怎么样?esg跨境电商有哪些功用?
  • 【动手学大模型开发】使用 LLM API:ChatGPT
  • 使用Curl进行本地MinIO的操作
  • 30天通过软考高项-第六天
  • MTKAndroid12-13-开机应用自启功能实现
  • Vue 对话框出现时,为什么滚动鼠标还是能滚动底层元素
  • Spring系列四:AOP切面编程第三部分
  • 软件工程(一):黑盒测试与白盒测试
  • 如何在WordPress网站中设置双重验证,提升安全性
  • 打火机检测数据集VOC+YOLO格式925张1类别
  • 案例篇:如何用tcpdump和Wireshark识别潜在威胁
  • Finish技术生态计划: FinishRpc
  • 无线采发仪多通道 在结构健康与地质灾害监测中的应用 VS-Box振弦、温度及多信号采发仪
  • 【Vue.js】Vue3父子组件数据通信案例(基础案例)
  • Vue组件开发进阶:从通信原理到DOM异步更新实战
  • 【北京】昌平区某附小v3700存储双控故障维修案例
  • leetcode刷题日记——两数相加
  • C++20 小语法
  • Dockerfile 编写根据需求阶段而出现
  • 【Redis】基础4:作为分布式锁
  • 克隆/备份后的虚拟机无法获取IP地址(FQA)
  • 微软编程一小时:探索 AI 世界
  • Prometheus 实战教程-搭建 Prometheus 环境
  • 现代c++获取linux系统指定网络接口的ip地址
  • 数字化时代软件检测机构如何保障软件质量、安全与合规性?
  • 【Linux实践系列】:进程间通信:万字详解命名管道实现通信
  • NGINX ngx_http_addition_module 模块响应体前后注入内容
  • NVIDIA新模型DAM-3B:描述一切,图像视频局部描述新突破