我有一组使用 ExecutorService
按系列执行的任务。
NullPointerException
大多数情况下都会抛出但并非总是。
我之前的所有任务都是从网站请求数据(除了这个),但它们都通过 SerializeService 将数据序列化到文件。
为什么会发生这种情况?我无法找出问题的根源。
任务:
...
Task<List<Course>> parseGradesTask = new Task<List<Course>>() {
@Override
public List<Course> call() {
return studentParser.parseStudentGrades();
}
};
Task<HashMap<String, String>> parseRegTask = new Task<HashMap<String, String>>() {
@Override
public HashMap<String, String> call() {
return studentParser.parseStudentRegistration();
}
};
parseGradesTask.setOnSucceeded(e -> {
List<Course> newList = parseGradesTask.getValue();
List<Course> newGrades = getNewlyListedCourses(newList);
if(!newGrades.isEmpty()) {
serializeService.serializeRecentCourses(newGrades);
setTableViewRecent();
notifyGrade(newGrades);
}
serializeService.serializeCourses(newList);
setTableViewCourses();
});
parseRegTask.setOnSucceeded(e-> {
// Exception starts from this line:
List<Course> regList = serializeService.fetchRegisterCourseList(parseGradesTask.getValue(), parseRegTask.getValue());
serializeService.serializeRegister(regList);
setTableViewReg();
});
ExecutorService es = Executors.newSingleThreadExecutor();
// other tasks
es.submit(() -> new Thread(parseGradesTask).start());
es.submit(() -> new Thread(parseRegTask).start());
es.shutdown();
获取方法时出现 NullPointerException:
public List<Course> fetchRegisterCourseList(List<Course> courseList, HashMap<String, String> courseIdList) {
List<Course> courseRegList = new ArrayList<>();
Iterator it = courseIdList.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
// NullPointerException on this line:
courseRegList.addAll(courseList.stream().filter(course ->
course.getCourseId().equals(pair.getKey()) && course.getCourseTitle().equals(pair.getValue()))
.collect(Collectors.toList()));
it.remove(); // avoids a ConcurrentModificationException
}
return courseRegList;
}
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException at com.example.test.service.Impl.SerializeServiceImpl.fetchRegisterCourseList(SerializeServiceImpl.java:100) at com.example.test.controller.MainController.lambda$syncCourses$4(MainController.java:450)
最佳答案
如果 parseRegTask
在 parseGradesTask
之前完成,则在 parseRegTask
的处理程序中,parseGradesTask.getValue()
将返回null
。当然,这个值作为 courseList
传递给 fetchRegisterCourseList
,并且 courseList.stream()
会抛出 NullPointerException
。由于每个任务都在自己的线程中运行,因此这显然是可能的。
我认为您打算在执行程序提供的单个线程上运行这两个任务。为此,您需要
es.submit(parseGradesTask);
es.submit(parseRegTask);
关于java - 任务未正确执行代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39679336/