首页 > 解决方案 > ExecutorService 未接来电

问题描述

我对 ExecutorService 有疑问,它不会执行所有调用。

public class MainClass {

    public static void main(String[] args) throws IOException, InvalidConnection, InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();

        XMLUrlService xmlUrlService = new XMLUrlService();
        LinkedBlockingQueue<String> linkedBlockingQueue = xmlUrlService.getAllXMLUrls();

        System.out.println(linkedBlockingQueue.size());
        for (int i = 0; i < linkedBlockingQueue.size(); i++) {

            executor.execute(new XMLParser(linkedBlockingQueue));
        }

        executor.shutdown();
    }

}

XMLUrlService 类返回一个 URL 列表,然后执行连接。

XMLPaser 是一个负责与给定 URL 建立连接的类。


public class XMLParser implements Runnable {


    private LinkedBlockingQueue queue;

    public XMLParser(LinkedBlockingQueue queue) {
        this.queue = queue;
    }

    public XMLParser(){}

    public void getRates(String data) throws IOException, XMLStreamException, InvalidConnection {

            URL url = new URL(data);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            InputStream inputStream = connection.getInputStream();

            inputStream.close();
            connection.disconnect();
    }


    public void run() {
            try {
                String data = (String) queue.take();
                getRates(data);

            } catch (InterruptedException | IOException ex) {
                //Handle exception
            } catch (InvalidConnection invalidConnection) {
                invalidConnection.printStackTrace();
            } catch (XMLStreamException e) {
                e.printStackTrace();
            }
    }
}

我的阻塞队列包含 250 个不同的 url 地址,但 executorservice 执行随机数量的调用(250 只是要测试的随机数量的元素)。我认为当我从队列中取出项目时,我可以省略一些,但我不确定。

标签: javamultithreading

解决方案


你应该改变三件事:

您执行任务的方式
您正在以一种非常奇怪的方式执行任务。而不是通过linkedBlockingQueue,通过String类似这样:

System.out.println(linkedBlockingQueue.size());
for (int i = 0; i < linkedBlockingQueue.size(); i++) {
    String url = linkedBlockingQueue.remove()
    executor.execute(new XMLParser(url));
}

处理异常的方式
不要吞下异常 - 最简单的方法是使用 aCallable而不是获取Futures 以便您以后可以检查您的任务发生了什么:

    ExecutorService executor = Executors.newCachedThreadPool();

    LinkedBlockingQueue<String> linkedBlockingQueue = new LinkedBlockingQueue<String>();

    System.out.println(linkedBlockingQueue.size());

    List<Future<Void>> result = linkedBlockingQueue.stream().map(
            url -> executor.submit(new XMLParser(url))
    ).collect(Collectors.toList());

    for (Future<Void> future : result) {
        try {
            future.get();
        } catch (Exception e) {
            System.out.println("Something happened:" + e);
        }
    }

    executor.shutdown();

等待执行 关闭执行器后,等待所有任务完成。

executor.shutdown();
executor.awaitTermination(10, TimeUnit.HOURS);

推荐阅读