Java JMH超时不';不要打断

Java JMH超时不';不要打断,java,jmh,Java,Jmh,在尝试处理JMH中的超时时,我发现所有超时实际上都不会导致任何中断。我可以将问题归结为以下几行: package main.java; import org.openjdk.jmh.Main; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.runner.RunnerException; import java.io.IOException; import java.util.concurrent.TimeUnit;

在尝试处理JMH中的超时时,我发现所有超时实际上都不会导致任何中断。我可以将问题归结为以下几行:

package main.java;

import org.openjdk.jmh.Main;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.RunnerException;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class TimeoutBenchmark {
    public static void main(String... args) throws IOException, RunnerException {
        Main.main(args);
    }

    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @Warmup(iterations = 0)
    @Timeout(time = 10, timeUnit = TimeUnit.SECONDS)
    public long benchmark() throws InterruptedException {
        Thread.sleep(20000);
        return 0;
    }
}
由于
Thread.sleep
处理中断,我希望每个迭代运行10秒,而不是20秒。然而,情况并非如此:

# JMH version: 1.20
# VM version: JDK 1.8.0_144, VM 25.144-b01
# VM invoker: C:\Program Files\Java\jdk1.8.0_144\jre\bin\java.exe
# VM options: -Dfile.encoding=UTF-8
# Warmup: <none>
# Measurement: 20 iterations, 1 s each
# Timeout: 10 s per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: main.java.TimeoutBenchmark.benchmark

# Run progress: 0,00% complete, ETA 00:03:20
# Fork: 1 of 10
Iteration   1: 20,004 s/op
Iteration   2: 20,009 s/op
Iteration   3: 20,009 s/op
Iteration   4: 20,014 s/op
Iteration   5: 20,003 s/op
Iteration   6: 20,003 s/op
Iteration   7: 20,003 s/op
#JMH版本:1.20
#虚拟机版本:JDK 1.8.0_144,虚拟机25.144-b01
#VM调用程序:C:\Program Files\Java\jdk1.8.0\U 144\jre\bin\Java.exe
#VM选项:-Dfile.encoding=UTF-8
#热身:
#测量:20次迭代,每次1s
#超时:每次迭代10秒
#线程:1个线程,将同步迭代
#基准模式:平均时间,时间/操作
#基准:main.java.TimeoutBenchmark.Benchmark
#运行进度:0,00%完成,预计时间00:03:20
#叉子:第1个,共10个
迭代1:20004 s/op
迭代2:20009 s/op
迭代3:20009 s/op
迭代4:20014 s/op
迭代5:20003 s/op
迭代6:20003 s/op
迭代7:20003 s/op

为什么呢?如何更改此代码,使每次迭代在10秒后实际中断?

BenchmarkHandler
中,在处理超时时,代码中有一条注释

//现在我们通信所有工作线程都应该停止
control.done();
//等待所有工人转移到拆卸区
control.awaitWarmdownReady();
//等待结果,处理超时
while(completed.size()
所以基本上这个超时只在拆卸阶段有效

然而,我认为这个注释的javadoc应该用这些信息进行修改

此处描述了拆卸:


此外,这封邮件也很有用:

有趣,我发现,尽管如此,这仍然表明至少应该有一个中断。尝试了不同的版本,但并不适用于所有版本…可能是一个错误。如果更改调用这些方法的顺序(超时检查和
waitwarmdownready()
),timeout工作得很好。谢谢你的信息!正如@Cargeh所建议的,更改方法调用的顺序成功了。我更改了顺序并修补了jmh jar。
    // now we communicate all worker threads should stop
    control.announceDone();

    // wait for all workers to transit to teardown
    control.awaitWarmdownReady();

    // Wait for the result, handling timeouts
    while (completed.size() < numThreads) {