为什么ListChangeBuilder会抛出NullPointerException?

时间:2018-03-16 10:26:30

标签: java javafx

我正在试图找出我收到此错误的原因:

java.lang.NullPointerException: null
    at javafx.collections.ListChangeBuilder.findSubChange(ListChangeBuilder.java:68)
    at javafx.collections.ListChangeBuilder.insertAdd(ListChangeBuilder.java:127)
    at javafx.collections.ListChangeBuilder.nextAdd(ListChangeBuilder.java:254)
    at javafx.collections.ObservableListBase.nextAdd(ObservableListBase.java:179)
    at javafx.collections.ModifiableObservableListBase.add(ModifiableObservableListBase.java:153)
    at java.util.AbstractList.add(AbstractList.java:108)
    at tech.dashman.dashman.RendererApp$1.handle(RendererApp.java:72)
    at tech.dashman.common.pubnub.NewScreenshotsToRender.handle(NewScreenshotsToRender.java:17)
    at tech.dashman.dashman.PubNubMessageHandler.lambda$message$0(PubNubMessageHandler.java:79)
    at java.lang.Thread.run(Thread.java:748)

我的应用程序发生了两次,但我不知道如何重现它。我的代码中触发错误的行是:

getActivity().add(new ActivityEntry("..."));

ActivityEntry是一个包含两个字段的简单类。我可以在必要时发布代码,但我认为这是无关紧要的。 activitygetActivity()返回的内容是这样定义的字段:

private ObservableList<ActivityEntry> activity = FXCollections.observableArrayList();

实际发生异常的方法如下所示:

private int findSubChange(int idx, final List<ListChangeBuilder.SubChange<E>> list) {
    int from = 0;
    int to = list.size() - 1;

    while (from <= to) {
        int changeIdx  = (from + to) / 2;
        ListChangeBuilder.SubChange<E> change = list.get(changeIdx);

        if (idx >= change.to) {
            from = changeIdx + 1;
        } else if (idx < change.from) {
            to = changeIdx - 1;
        } else {
            return changeIdx;
        }
    }
    return ~from;
}

第68行,提出异常的是:

if (idx >= change.to) {

除了ListChangeBuilder中的错误之外,我唯一能想到的是它是一个竞争条件,两个线程同时修改了ObservableList。这看起来像那样吗? ObservableList不是线程安全的吗?

1 个答案:

答案 0 :(得分:0)

这看起来像一个多线程问题,所以,现在,我的解决方案是以这种方式定义列表:

private ObservableList<ActivityEntry> activity = FXCollections.synchronizedObservableList(FXCollections.observableArrayList());

由于多线程问题难以重现和调试,我不知道这是否真的解决了这个问题。我猜是否不会在生产中再次注意到它。