SDm*_*try 3 java concurrency java.util.concurrent java-8
方法getFirst()和getSecond()这个类的同时被调用.它是Web应用程序的一部分.
内部地图也填充,没有并发.
public class MyClass {
private Map<String, List<List<String>>> first;
private Map<String, List<List<String>>> second;
public MyClass() {
first = new ConcurrentHashMap<>();
second = new ConcurrentHashMap<>();
}
public Set<String> getFirst(String key, String token, int a, int b) {
return get(first, key, token, a, b);
}
public Set<String> getSecond(String key, String token, int a, int b) {
return get(second, key, token, a, b);
}
private Set<String> get(final Map<String, List<List<String>>> map, final String key, final String token,
final int a, final int b) {
Set<String> result = new TreeSet<>();
map.get(key).stream().filter(i -> i.size() <= b && i.size() >= a).forEach(
s -> result
.addAll(s.stream().filter(p -> StringUtils.containsIgnoreCase(p, token)).collect(Collectors.toList())));
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
我用类似ab -n 10000 -c 100(Apache的实用程序)测试它.我记录下来了.我总是得到同样的一套.但是,如果我改map.get(key).stream()到map.get(key).parallelStream()并做相同的步骤,我得到有时不同结果的大小(总是更小).
它是什么?
您正在使用并行流TreeSet.addAll()内部forEach.该forEach体可以同时执行多次在不同的线程对不同的元素TreeSet不是线程安全的.要快速解决问题,您可以同步修改result或使用forEachOrdered.但是,它会更flatMap流畅,更高效,您可以立即收集它forEach.试试这个版本:
return map.get(key).stream()
.filter(i -> i.size() <= b && i.size() >= a)
.flatMap(List::stream).filter(p -> StringUtils.containsIgnoreCase(p, token))
.collect(Collectors.toCollection(TreeSet::new));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
120 次 |
| 最近记录: |