在Java中安排例外

时间:2015-11-30 19:58:37

标签: java multithreading exception quartz-scheduler

我正在开发一项需要从给定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;
}

这是下载工作者:

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状态会更容易,因此它会返回异常。

2 个答案:

答案 0 :(得分:0)

java executors是另一种选择(参见ExecutorService

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

答案 1 :(得分:0)

DownloadWorker中,睡眠6秒,当您在Future主题中获得DownloadManager时,请将timeout设置为5秒。现在您将获得timeout例外。

通过这种方式,列出要Exceptions个帖子中的DownloadManager,并将其从DownloadWorker中删除。

其他方法是在执行方法之后覆盖ThredPoolExecutor

Handling exceptions from Java ExecutorService tasks

请注意,FutureTask会吞下异常(如果您在ExecutorService上使用submit()而不是execute()。请查看来源code。因此,从{{0}}正确引发异常{1}}。