Java命令行应用程序以某种方式保留状态

时间:2018-04-13 10:18:20

标签: java maven command-line

前言:如果这是一个非常愚蠢的错误或事实上已有详细记录,我会道歉。对我来说,这似乎很奇怪,完全没有意义。

应用程序

我在macOS 10.13.4上使用IntelliJ IDEA Ultimate内置了一个Java命令行应用程序,它使用下面列出的四个Maven库。其目的是从网站下载文件,并在分页结果中导航。

此应用程序的一个功能是能够在循环中继续运行,如果在完成当前扫描时已经过了足够的时间,则检查新结果。为此,它会将Thread.sleep(remainingMillis)作为do-while块中while条件的一部分进行调用。

问题

应用程序没有任何问题,但是在引入Thread.sleep()调用之后(我怀疑这是一个麻烦的行),会发生一些非常奇怪的行为:应用程序执行第一次运行没有问题,从中获取三个项目配置的网站;然后将其配置为确保在再次运行之前已经过了60秒。但是在进行后续运行时,日志表明它开始查看第31页(作为示例),而不是扫描结果的第一页,而是找不到结果。找不到任何东西后,在第32页尝试三个中的两个,最后一次尝试查看第33页;然后它再次等待,直到扫描迭代开始后已经过了60秒。

我无法证实这一点,但似乎它会在后续扫描中继续计算:34,35,然后是36,然后再等待。但是,代码会建议在while的另一次迭代启动时,这应该再次从1开始。

这可能是IntelliJ或Java播放,它可能只需要清理bin / obj文件夹,但如果这是由于我的代码,我宁愿知道它,所以我不喜欢'在未来遇到同样愚蠢的问题。

观察

几天后使用当前配置运行应用程序意味着它不会调用Thread.sleep(),因为超过60秒通过,所以它会立即继续下一次迭代;当发生这种情况时,奇怪的页面索引递增问题并没有发挥作用 - 相反,下一次迭代将从第1页继续进行。

然后,在开始下一次迭代之前运行它以使其Thread.sleep()几秒钟没有引起问题......非常奇怪。这是一个梦吗?

守则

旁注:我添加了Thread.currentThread().interrupt()来尝试修复此问题,但它似乎没有效果。

public static void main(String[] args) {
        do {
            startMillis = System.currentTimeMillis();
            int itemsFetched = startFetching(agent, config, record, 1, 0);
        } while (shouldRepeat(config.getRepeatSeconds(), startMillis));
    }

    private static boolean shouldRepeat(int repeatSeconds, long startMillis) {
        long passedMillis = System.currentTimeMillis() - startMillis;
        int repeatMillis = repeatSeconds * 1000;
        boolean repeatSecondsReached = passedMillis >= repeatMillis;

        if (repeatSeconds < 0) {
            return false;
        } else if (repeatSecondsReached) {
            return true;
        }

        long remainingMillis = repeatMillis - passedMillis;
        int remainingSeconds = (int) (remainingMillis / 1000);
        try {
            Thread.sleep(remainingMillis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException(e);
        }

        return true;
    }

    private static int startFetching(Agenter agent, MyApplicationConfig config, MyApplicationRecord record, int pageIndex, int itemsFetched) {
        String categoryCode = config.getCategoryCode();
        List<Item> items = agent.getPageOfItems(categoryCode, pageIndex, config);

        if (items == null) {
            return itemsFetched;
        }

        int maxItems = config.getMaxItems();

        try {
            for (Item item : items) {
                String itemURL = item.getURL();

                agent.downloadItem(itemURL, config, item.getItemCount());
                itemsFetched++;

                if (maxItems > 0 && itemsFetched >= maxItems) {
                    return itemsFetched;
                }
            }
        } catch (IOException e) {
           // Log
        }

        return startFetching(agent, config, record, pageIndex + 1, itemsFetched);
    }
}

Maven图书馆

  • commons-cli:commons-cli:1.4
  • org.apache.logging.log4j:log4j-api:2.11.0
  • org.apache.logging.log4j:log4j-core:2.11.0
  • org.jsoup:jsoup:1.11.2

1 个答案:

答案 0 :(得分:0)

在调用中检查您的Agenter实现  agent.getPageOfItems提供了pageIndex,但可以将其存储在实例变量或类似的东西中。错误本身可能是在其他调用上它可能没有被重置(正确)。