我正在开发一个任务,需要从给定的 URL 下载文件,其中一个要求是它可以处理网络故障和异常。
在我的实现中,我有一个 DonwloadManager 为每个 URL 分配一个线程,以免阻塞。
问题是我不确定如何通过代码模拟失败和异常,我尝试使用 Quartz 作为调度程序和一个仅抛出异常的作业,但据我所知调度程序在不同的线程上运行,所以这不会完全影响下载线程。
有没有办法模拟下载线程中的异常?
这是我的代码以获得更多见解:
public class DownloadManager {
int allocatedMemory = 0;
void validateURLs(String[] urls) {
if (urls.length == 0) {
throw new IllegalArgumentException("URLs List is empty");
}
}
public ArrayList<Status> downloadURLs(String[] urls, int memorySize) throws Exception {
validateURLs(urls);
ExecutorService executor = Executors.newWorkStealingPool();
CompletionService<Status> completionService = new ExecutorCompletionService<Status>(executor);
ArrayList<Status> downloadStatus = new ArrayList<Status>();
allocatedMemory = memorySize / urls.length;
for (String url : urls) {
completionService.submit(new DownloadWorker(url, allocatedMemory));
}
for(int i=0;i<urls.length;i++){
Future<Status> URLStatus = completionService.take();
System.out.println(URLStatus.get());
downloadStatus.add(URLStatus.get());
}
executor.shutdown();
return downloadStatus;
}
这是下载的 Worker:
class DownloadWorker implements Callable<Status> {
static final int SUCCESS = 1, FAILURE = 0;
private int bufferSize;
private String assignedURL;
public DownloadWorker(String assignedURL, int bufferSize) {
this.bufferSize = bufferSize;
this.assignedURL = assignedURL;
}
public Status call() throws Exception {
URLConnection openConnection = new URL(assignedURL).openConnection();
openConnection.addRequestProperty("User-Agent",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/39.0");
String outputFileName = assignedURL.substring(assignedURL.lastIndexOf("/") + 1);
RandomAccessFile outputFile = new RandomAccessFile(outputFileName, "rw");
ReadableByteChannel inputChannel = Channels.newChannel(openConnection.getInputStream());
FileChannel outputChannel = outputFile.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
while (inputChannel.read(buffer) > 0) {
buffer.flip();
for (int i = 0; i < buffer.limit(); i++) {
outputChannel.write(buffer);
}
buffer.clear();
}
outputChannel.close();
inputChannel.close();
outputFile.close();
return new Status(assignedURL, true);
}
}
关于如何以编程方式模拟/测试异常有什么建议吗?
更新:我在想,与其调度异常,不如模拟生成的 Future 状态,以便它返回异常会更容易。
In your DownloadWorker
,睡眠 6 秒,当您得到Future
in DownloadManager
线程、集合timeout
为 5 秒。现在你会得到timeout
例外。
这样,列出来Exceptions
你想赶上DownloadManager
线程并将它们从你的DownloadWorker
.
其他方式是压倒性的ThredPoolExecutor
按照此执行方法后:
处理 Java ExecutorService 任务的异常
注意FutureTask
s 吞掉异常(如果你使用submit()而不是execute())ExecutorService
。看一下源码code。因此,正确地引发异常DownloadWorker
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)