Java - 为什么静态块中的方法没有及时加载?

Java - why is a method from a static block not getting loaded in time?

我编写了一个方法 processMetrics,如果包含数据的文件自上次请求以来已更新,则加载新指标。我希望该方法每 10 秒执行一次,因此决定为此目的使用 ExecutorService

但是,当我测试 class 中使用配置的方法时。我可以看到调用该方法时执行程序没有从静态块加载配置。 当我 运行 未先调用注释行就进行测试时,它 returns false 因为没有更新配置。 但是当我 运行 MetricsProcessor.isMetricValid("Metric_1"); 然后 assertTrue(MetricsProcessor.isMetricValid("Metric_1"));配置已加载且测试 returns 为真。

什么会导致这种行为?我得出的结论是,这是因为 MetricsProcessor class 没有及时加载。这是一个有效的假设吗?

此外,我已经设法通过在执行程序之前的静态块的第一行中显式调用 processMetrics(); 来解决问题。但是还是不太明白为什么会这样?

@Test
    public void testIsMetricValid() {
//        MetricsProcessor.isMetricValid("Metric_1");
        assertTrue(MetricsProcessor.isMetricValid("Metric_1"));
    }


// MetricsProcessor is a final class
private static Runnable loadMetrics = MetricsProcessor::processMetrics;
private static ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

static {
        executor.scheduleAtFixedRate(processMetrics, 0, 10, TimeUnit.SECONDS);
    }

private static void processMetrics() {
 {
            long metricsLastMod = metricsFile.lastModified();

            if (metricsLastMod > lastMod.get()) {
                processMetricsData(metricsFile);
            lastMod.set(metricsLastMod);
            }
}

您面临竞争条件。有两个线程:

  • 加载您的 class 然后 运行 测试
  • 正在执行计划任务

在某些情况下,调度程序可能比您的测试启动得更快。但不能保证。因此,为了防止竞争条件,您至少需要确保任务的第一次执行。

这是解决方案之一:

private static Runnable loadMetrics = MetricsProcessor::processMetrics;
private static ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

static {
    loadMetrics.run();
    // Note the updated initial delay. 
    executor.scheduleAtFixedRate(loadMetrics, 10, 10, TimeUnit.SECONDS);
}