1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
| @BenchmarkMode({Mode.AverageTime}) //平均响应时间模式
@OutputTimeUnit(TimeUnit.MILLISECONDS) //输出单位:毫秒模式
@State(Scope.Benchmark) //作用域为本次JMH测试,线程共享
@Fork(value = 1) //fork出一个JVM进程
@Threads(4) //使用4个线程去执行测试方法
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) //预热迭代5次,每次一秒
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) //测试迭代5次,每次一秒
public class ThreadTest {
@Param({"500", "1000", "2000"}) //模拟任务调度次数,分别500次,1000次,2000次
private int loop;
@Param({"50", "100", "200"}) //模拟线程池大小,也是虚拟线程调度器大小
private int nThreads;
private ExecutorService executor;
private ExecutorService virtualExecutor;
@Setup //每个测试方法前初始化
public void setup() {
//普通线程方式
executor = Executors.newFixedThreadPool(nThreads);
//定义虚拟线程调度器大小,保持跟平台线程池大小一样
System.setProperty("jdk.virtualThreadScheduler.maxPoolSize", String.valueOf(nThreads));
virtualExecutor = Executors.newVirtualThreadPerTaskExecutor();
}
@TearDown //每个测试方法执行后销毁
public void tearDown() {
executor.close();
virtualExecutor.close();
}
//主函数启动测试
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder().include(ThreadTest.class.getSimpleName()).build();
new Runner(opt).run();
}
//普通线程测试用例
@Benchmark
public void platformThreadTest(Blackhole bh) {
//模拟多个任务调度测试,返回最终结果
List<Integer> result = execute(loop, executor, ThreadTest::sleepTime);
bh.consume(result);
}
//虚拟线程测试用例
@Benchmark
public void virtualThreadTest(Blackhole bh) {
//模拟多个任务调度测试,返回最终结果
List<Integer> result = execute(loop, virtualExecutor, ThreadTest::sleepTime);
bh.consume(result);
}
//模拟多个任务调度测试,返回最终结果
private static <T> List<T> execute(int loop, ExecutorService executor, Supplier<T> supplier) {
CompletableFuture<T>[] futures = new CompletableFuture[loop];
for (int i = 0; i < loop; i++) {
//模拟执行耗时任务
futures[i] = CompletableFuture.supplyAsync(supplier, executor);
}
CompletableFuture<Void> result = CompletableFuture.allOf(futures);
result.join();
return Stream.of(futures).map(f -> f.getNow(null)).filter(Objects::nonNull).collect(Collectors.toList());
}
//sleep方法,模拟耗时IO操作,目前暂定30ms
@SneakyThrows
private static int sleepTime() {
Thread.sleep(Duration.ofMillis(sleepTimeMillis));
return sleepTimeMillis;
}
...
}
|