YNZH's Blog

数据集

http://static.yximgs.com/kos/nlav10305/warmup-test/warmup-test.data.z01
http://static.yximgs.com/kos/nlav10305/warmup-test/warmup-test.data.z02
http://static.yximgs.com/kos/nlav10305/warmup-test/warmup-test.data.z03
http://static.yximgs.com/kos/nlav10305/warmup-test/warmup-test.data.z04
http://static.yximgs.com/kos/nlav10305/warmup-test/warmup-test.data.z05
http://static.yximgs.com/kos/nlav10305/warmup-test/warmup-test.data.z06
http://static.yximgs.com/kos/nlav10305/warmup-test/warmup-test.data.z07
http://static.yximgs.com/kos/nlav10305/warmup-test/warmup-test.data.zip

运行参数

-XX:+UseG1GC -XX:MaxGCPauseMillis=500 -Xss256k -Xms4G -Xmx4G -Xms4g -Xmx4g -XX:+UnlockCommercialFeatures

日志:

并行:2020-05-26———19点31分

268s —> 串行执行。r:1,Core:4,CorePoolSize:8,FileBlock:512M

???s —> 串行执行。r:1,Core:4,CorePoolSize:8,FileBlock:1G

BUG

bug_01

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
/**
* 有一个ConcurrentHashMap map,key类型String,value类型ConcurrentLinkedQueue<Integer>
* 需要并发的对map进行写入操作,其中可能存在两个线程同时对map写入同一个key的情况。但是map的值类型
* 为并发队列,需要先获取队列的引用,然后操作这个引用。
**/

//bug 代码
ConcurrentLinkedQueue<Integer> queueVal = null;
for (int j = 0; j < length; j++) {
String key = KEY_NAME;
//如果对应的key不存在 则初始化一个queue
if ((queueVal = readerMap.get(key)) == null) {
queueVal = new ConcurrentLinkedQueue<>();
//其他线程初始化了队列,这里不能使用put,因为会覆盖掉已经存在的队列,引起数据丢失!!!!!
if (readerMap.put(key, queueVal) != null) {
queueVal = readerMap.get(key);
}
}
queueVal.add(j);
}

// fixed bug
for (int j = 0; j < length; j++) {
String key = KEY_NAME;
//如果对应的key不存在 则初始化一个queue ------使用DCL
if ((queueVal = readerMap.get(key)) == null) {
lock.lock()
try{
if ((queue{Val = readerMap.get(key)) == null){
queueVal = new ConcurrentLinkedQueue<>();
readerMap.put(key, queueVal);
queueVal = readerMap.get(key);
}
}finally{
lock.unlock();
}
}
queueVal.add(j);
}

优化

String的初始化

version_0

1
2
3
4
5
6
while(i<40000000){ //四千万次
String stamp = new String(aLineBytes, 0, len, StandardCharsets.UTF_8);
String methodName = new String(aLineBytes, s1, len1, StandardCharsets.UTF_8);
String value = new String(aLineBytes, s1, len2, StandardCharsets.UTF_8
}
// run time 9s~10s

version_1

1
2
3
4
5
6
while(i<40000000){ //四千万次
String stamp = new String(aLineBytes, 0, len);
String methodName = new String(aLineBytes, s1, len1);
String value = new String(aLineBytes, s1, len2);
}
// run time 8s~9s,因为version_0中每次都会创建新的StringDecoder对象影响性能

version_2

1
2
3
4
5
6
7
8
9
String stamp = null;
String methodName = null;
String value = null;
while(i<40000000){ //四千万次
stamp = new String(aLineBytes, 0, len);
methodName = new String(aLineBytes, s1, len1);
value = new String(aLineBytes, s1, len2);
}
//run time 8s, 相比version_1 极大的减少了内存中引用的个数

 评论


博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议

本站使用 Material X 作为主题 , 总访问量为 次 。
载入天数...载入时分秒...