Java - 使用线程池并发发送多个文件时出错

醉酒字节

我正在尝试同时将一些文件发送到 rest api。试图实施这个答案

public class UploadThread implements Runnable {

    private File file;

    public UploadThread(File file) {
        this.file = file;
    }

    @Override
    public void run() {
        try {
            String url = // api url

            URL server = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) server.openConnection();

            // setting request properties here

            connection.connect();

            OutputStream out = connection.getOutputStream();
            FileInputStream in = new FileInputStream(file);

            try {
              // write to outputstream

            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                out.close();
                in.close();

                if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                    // error handling here
                }

                connection.disconnect();            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

public class UploadTest {

    public static void main(String[] args) throws Exception {

        List<File> files = Files.walk(Paths.get("/home/random"))
                                .filter(Files::isRegularFile)
                                .map(Path::toFile)
                                .collect(Collectors.toList());

        ExecutorService executorService = Executors.newFixedThreadPool(5);

        for(File file : files) {
            Runnable worker = new UploadThread(file);

            executorService.execute(worker);
        }

        executorService.shutdown();

        while(!executorService.isTerminated()) {
            //
        }

        System.out.println("upload finished....");

    }
}

我在random目录中有 10 个文件

当我执行这个时,第一个文件的发送次数与我在Executors.newFixedThreadPool()方法中分配的线程数完全相同

如果我分配 5 个线程,则第一个文件(每次执行时不同)将发送 5 次,而其余文件仅发送一次!对于 10 个线程,发送 10 次!

为什么只有一个文件被多次发送,而其余的则不是?我在代码中做错了什么?

编辑:我将文件发送到的 api 正在使用Jerseyon Tomcat 8以下是文件的处理方式。

在资源上

@Path("file")
public class MyResource {

    private StorageManager storageManager;

    public MyResource() {
        this.storageManager = new StorageManager();
    }

    @GET
    @Path("upload")
    @Consumes(MediaType.APPLICATION_OCTET_STREAM)
    public Response upload(InputStream inputStream) {
        return this.storageManager.upload(inputStream);
    }
}

StorageManager

public class StorageManager {

    public Response upload(InputStream inputStream) {

        // handling file upload here
        // this method is called 5 or 10 times for one file

        // return some response
    }
}

对于单个文件,这工作得很好。我已经使用 REST 客户端上传了数百个文件,并且每次都有效。但是对于并发请求,此upload()方法会为任何一个文件(第一个)调用多次。

M.勒吕特

试过你的代码,似乎工作正常。顺便说一句,没有必要将 a 映射Path到 aFile因为Files.copy您可以轻松地将 a 的内容复制Path到 an OutputStream

public class UploadThread implements Runnable {

   private Path file;

   public UploadThread(Path file) {
    this.file = Objects.requireNonNull(file);
   }

 @Override
  public void run() {
    try {
        String url = // api url

        URL server = new URL(url);
        HttpURLConnection connection = (HttpURLConnection) server.openConnection();

        // setting request properties here

        connection.connect();

        try (OutputStream out = connection.getOutputStream()) {
            Files.copy(file, out);
          } finally {
            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                // error handling here
            }

            connection.disconnect(); 
          }           
    } catch (Exception e) {
        e.printStackTrace();
    }
  }
}

您还可以放弃for和 'while' 循环:

public static void main(String[] args) throws Exception {
    ExecutorService executorService = Executors.newFixedThreadPool(5);
    Files.walk(Paths.get("/home/random"))
                            .filter(Files::isRegularFile)
                            .map(UploadThread::new)
                            .forEach(executorService::execute);

    executorService.shutdown();
    System.out.println("upload finished....");
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Java并发-线程池-多个请求和用户

来自分类Dev

使用线程池时,如何在Java中使线程空闲?

来自分类Dev

使用线程池执行任务时出现RejectedExecutionException:JAVA

来自分类Dev

Java线程池目的

来自分类Dev

使用WindowBuilder SWT时Java中有多个线程

来自分类Dev

Java线程并发

来自分类Dev

Java并发唤醒线程

来自分类Dev

JAVA线程池重用线程

来自分类Dev

从Java邮件发送时出错(SSLHandShake异常)

来自分类Dev

如何编写Java线程池程序以读取文件内容?

来自分类Dev

如何编写Java线程池程序以读取文件内容?

来自分类Dev

Flutter:线程“ main”中的异常java.util.zip.ZipException:打开zip文件时出错

来自分类Dev

尝试使用Java SAX解析excel xml文件时出错

来自分类Dev

Java-何时使用固定大小的线程池和可变大小的线程池?

来自分类Dev

Java-何时使用固定大小的线程池和可变大小的线程池?

来自分类Dev

从Java / Spring将文件发送到AWS S3时出错

来自分类Dev

为什么异步AWS Java SDK使用线程池?

来自分类Dev

Java:使用多个线程将消息发送到JMS队列

来自分类Dev

Java的旗语availablePermits与线程池

来自分类Dev

Java-重用线程池

来自分类Dev

在 Java Eclipse 中使用 Selenium WebDriver 启动 Chrome 时出错 - 线程“main”中的异常

来自分类Dev

Java多线程中的并发

来自分类Dev

使用LibUsb在Java中通过USB发送数据时出错(未找到实体)

来自分类Dev

在Java回调中发送多个文件?

来自分类Dev

从java中的jar导入文件时出错

来自分类Dev

从Java中的文件读取时出错

来自分类Dev

执行Java类文件时出错

来自分类Dev

在Java中读取文件时出错

来自分类Dev

编译Java文件脚本时出错

Related 相关文章

热门标签

归档