我的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仅是要测试的随机元素数量)。我认为当我从队列中取出物品时,我可以省略一些物品,但是我不确定。

最佳答案

您应该更改三件事:

您执行任务的方式
您以一种非常奇怪的方式执行任务。像这样传递linkedBlockingQueue而不是传递String

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


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

    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);

关于java - ExecutorService未接来电,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55881246/

10-12 22:11