在Java中安排例外

我正在开发一个需要从给定URL下载文件的任务,其中一个要求是它可以处理网络故障和exception。

在我的实现中,我有一个DonwloadManager为每个URL分配一个线程,以免被阻塞。

问题是我不知道如何通过代码模拟失败和exception,我尝试使用Quartz作为调度程序和只抛出exception的作业,但据我所知,调度程序在不同的线程上运行,所以这不会完全影响下载线程。

有没有办法在下载线程中模拟exception?

以下是我的更多见解的代码:

public class DownloadManager { int allocatedMemory = 0; void validateURLs(String[] urls) { if (urls.length == 0) { throw new IllegalArgumentException("URLs List is empty"); } } public ArrayList downloadURLs(String[] urls, int memorySize) throws Exception { validateURLs(urls); ExecutorService executor = Executors.newWorkStealingPool(); CompletionService completionService = new ExecutorCompletionService(executor); ArrayList downloadStatus = new ArrayList(); allocatedMemory = memorySize / urls.length; for (String url : urls) { completionService.submit(new DownloadWorker(url, allocatedMemory)); } for(int i=0;i<urls.length;i++){ Future URLStatus = completionService.take(); System.out.println(URLStatus.get()); downloadStatus.add(URLStatus.get()); } executor.shutdown(); return downloadStatus; } 

这是下载工作者:

 class DownloadWorker implements Callable { 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); } 

}

有关如何以编程方式模拟/测试exception的任何建议?

更新:我在想,不是调度exception,而是模拟生成的Future状态会更容易,因此它会返回exception。

在您的DownloadWorker ,睡眠6秒,当您在DownloadManager线程中获取Future时,将timeout设置为5秒。 现在你将获得timeoutexception。

通过这种方式,列出要在DownloadManager线程中捕获的Exceptions并从DownloadWorker抛出它们。

其他方法是在执行方法之后重写ThredPoolExecutor

处理Java ExecutorService任务中的exception

注意FutureTask吞下exception(如果你在ExecutorService上使用submit()而不是execute()。看看源代码 。所以从DownloadWorker正确引发exception。

java executors是另一个选项(参见ExecutorService )

  • 您可以在执行程序中使用awaitTermination方法在当前线程中等待所有任务完成
  • 检查Future(在提交时返回的元素)的exception