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