[英]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.