簡體   English   中英

Java-使用線程池同時發送多個文件時出錯

[英]Java - Error sending multiple files concurrently using threadpool

我正在嘗試同時將一些文件發送到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在Tomcat 8上使用Jersey 這是文件的處理方式。

在資源上

@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()方法。

嘗試過您的代碼,似乎工作正常。 順便說一下,不需要將Path映射到File因為使用Files.copy可以輕松地將Path的內容復制到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....");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM