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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
| package priv.explore8.demo;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.thread.ThreadUtil;
import com.google.common.collect.Lists;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.StampedLock;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.assertEquals;
class LockPerformanceDemoTest {
private LockPerformanceDemo service;
/**
* 运行多少组
*/
public int groupNumber;
/**
* 每组运行的次数
*/
public int perGroupNumber;
public List<Long> timeCountList;
@BeforeEach
void setUp() {
service = new LockPerformanceDemo();
}
@AfterEach
void afterEach() {
assertEquals((long) groupNumber * perGroupNumber, service.getResources());
}
@ParameterizedTest
@CsvSource({"20, 100", "20, 1000"})
void syncByMethod(int groupCount, int perGroupCount) {
groupNumber = groupCount;
perGroupNumber = perGroupCount;
timeCountList = Lists.newArrayListWithCapacity(groupNumber * perGroupCount);
reduce("syncByMethod", service::syncByMethod);
// syncByMethod 方式, 共执行 20组,每组 100次,最长耗时 2540毫秒, 最短耗时 128毫秒, 平均耗时 1414.950000毫秒
// syncByMethod 方式, 共执行 20组,每组 1000次,最长耗时 25461毫秒, 最短耗时 3702毫秒, 平均耗时 19282.150000毫秒
}
@ParameterizedTest
@CsvSource({"20, 100", "20, 1000"})
void syncByThis(int groupCount, int perGroupCount) {
groupNumber = groupCount;
perGroupNumber = perGroupCount;
timeCountList = Lists.newArrayListWithCapacity(groupNumber * perGroupCount);
reduce("syncByThis", service::syncByThis);
// syncByThis 方式, 共执行 20组,每组 100次,最长耗时 2564毫秒, 最短耗时 127毫秒, 平均耗时 1542.350000毫秒
// syncByThis 方式, 共执行 20组,每组 1000次,最长耗时 25560毫秒, 最短耗时 3598毫秒, 平均耗时 19210.350000毫秒
}
@ParameterizedTest
@CsvSource({"20, 100", "20, 1000"})
void syncByConstant(int groupCount, int perGroupCount) {
groupNumber = groupCount;
perGroupNumber = perGroupCount;
timeCountList = Lists.newArrayListWithCapacity(groupNumber * perGroupCount);
reduce("syncByConstant", service::syncByConstant);
// syncByConstant 方式, 共执行 20组,每组 100次,最长耗时 2541毫秒, 最短耗时 128毫秒, 平均耗时 1485.900000毫秒
// syncByConstant 方式, 共执行 20组,每组 1000次,最长耗时 25605毫秒, 最短耗时 14804毫秒, 平均耗时 21494.650000毫秒
}
@ParameterizedTest
@CsvSource({"20, 100", "20, 1000"})
void stampedLock(int groupCount, int perGroupCount) {
groupNumber = groupCount;
perGroupNumber = perGroupCount;
timeCountList = Lists.newArrayListWithCapacity(groupNumber * perGroupCount);
service.setLock(new StampedLock());
reduce("stampedLock", service::stampedLock);
// stampedLock 方式, 共执行 20组,每组 100次,最长耗时 2541毫秒, 最短耗时 2419毫秒, 平均耗时 2497.800000毫秒
// stampedLock 方式, 共执行 20组,每组 1000次,最长耗时 25272毫秒, 最短耗时 25085毫秒, 平均耗时 25215.000000毫秒
}
@ParameterizedTest
@CsvSource({"20, 100", "20, 1000"})
void reentrantLock(int groupCount, int perGroupCount) {
groupNumber = groupCount;
perGroupNumber = perGroupCount;
timeCountList = Lists.newArrayListWithCapacity(groupNumber * perGroupCount);
service.setReentrantLock(new ReentrantLock());
reduce("reentrantLock", service::reentrantLock);
// reentrantLock 方式, 共执行 20组,每组 100次,最长耗时 2550毫秒, 最短耗时 128毫秒, 平均耗时 1479.400000毫秒
// reentrantLock 方式, 共执行 20组,每组 1000次,最长耗时 25592毫秒, 最短耗时 1362毫秒, 平均耗时 16253.050000毫秒
}
/**
* 指定任务,并统计运行的时长
*
* @param taskName 任务名称
* @param task 任务
*/
private void reduce(String taskName, Runnable task) {
// 对 runAndRecordTime 执行 groupNumber 次
ThreadUtil.concurrencyTest(groupNumber, () -> runAndRecordTime(taskName, task));
// @formatter:off
System.err.printf("%s 方式, 共执行 %d组,每组 %d次,最长耗时 %d毫秒, 最短耗时 %d毫秒, 平均耗时 %f毫秒 \n",
taskName, groupNumber, perGroupNumber, CollUtil.max(timeCountList), CollUtil.min(timeCountList),
timeCountList.stream().collect(Collectors.averagingLong(Long::longValue)));
// @formatter:on
}
/**
* 指定任务,并运行。记录每组执行的耗时时长
*
* @param taskName 任务名称
* @param task 任务
*/
private void runAndRecordTime(String taskName, Runnable task) {
TimeInterval timer = DateUtil.timer();
for (int i = 0; i < perGroupNumber; i++) {
task.run();
}
long time = timer.intervalMs();
timeCountList.add(time);
System.out.printf("%s 方式执行 %d次, 用时 %d 毫秒 \n", taskName, perGroupNumber, time);
}
}
|