工作一年了,感觉还是要多记录一些东西,系统地总结太费时间,可能更多是一些细碎的东西。
1、一个并发bug
Map<Long, List<String>> map;
List<String> partition = Lists.newArrayList();
for(Map.Entry<Long, List<String>> entry : map.entrySet()){
partition.addAll(entry.getValue());
if(partition .size() >= 1000) {
threadPool.submit(() -> doSomething(Lists.newArrayList(partition)));
partition.clear();
}
}
threadPool.submit(() -> doSomething(partition));
将map值中的list按1000个分批,丢到线程池里执行业务逻辑。
有个致命的问题,
threadPool.submit(() -> doSomething(Lists.newArrayList(partition)))
这行代码,因为是丢给线程池,其他线程还没执行Lists.newArrayList(partition),主线程就执行了partition的clear和addAll()操作,最后丢到线程里的全是同一个list,即最后一行中的partition。
解决方法:
List copy = Lists.newArrayList(partition);
threadPool.submit(() -> doSomething(copy));
2、字节码验证错误
报错内容类似https://www.cnblogs.com/zhangcybb/p/4897417.html
java.lang.VerifyError: Inconsistent stackmap frames at branch target
JVM验证字节码时出现不一致(TODO,具体的验证时机、验证原理),常见于javassit,cglib等字节码生成工具。
JDK1.7及之前可以通过加上VM options : -XX:-UseSplitVerifier禁用字节码验证,1.8及以后加上-noverify