观看在线产品时出现错误,代码是这样的,但是NullPointedException
困扰着我,此错误仅出现一次,并且我无法再次出现。我不明白为什么ArrayList
是[null, 1]
:
public void test4() {
class PlayerTask {
List<Integer> targetValueList;
List<Integer> getTargetValueList() {
if (null == targetValueList) {
init();
}
return targetValueList;
}
private void init() {
targetValueList = new ArrayList<>();
targetValueList.add(Integer.parseInt("1"));
}
}
PlayerTask task = new PlayerTask();
//some code1
new Thread(() -> {
task.getTargetValueList().get(0); // NullPointException ,real array is [null, 1]
}).start();
//some code2
new Thread(() -> {
task.getTargetValueList().size();
}).start();
// some code ...
new Thread(() -> {
task.getTargetValueList().get(0);
}).start();
// ....
///task.getTargetValueList().get(..)...
}
答案 0 :(得分:4)
您的代码是多线程的,但是在创建和访问new ArrayList<>()
时您无法防范可能的race condition。解决此问题的最快方法是使用synchronize
getTargetValueList()
方法:
synchronized List<Integer> getTargetValueList() {
if (null == targetValueList) {
init();
}
return targetValueList;
}
花点时间阅读Safe Publication and Safe Initialization in Java。它为如何改进此方法提供了深刻的见解,以及为什么像双重检查锁定之类的某些模式不是一个好主意。
如果您想了解有关并发的更多信息,那么本书Java Concurrency in Practice是一个很好的起点。