Java-链​​表 : Weird NullPointerException

标签 java nullpointerexception linked-list

我对 NullPointerException 有一个小问题,我无法真正理解。

我的代码全天候运行 24/7 并且运行良好,但我有一个异常,它会在应用程序启动后的 1 天到 1 周内随机弹出。

这是堆栈跟踪:

java.lang.NullPointerException
at java.util.LinkedList.get(LinkedList.java:477)
at com.ch4process.acquisition.ScenarioWorker.eventHandling(ScenarioWorker.java:97)
at com.ch4process.acquisition.ScenarioWorker.call(ScenarioWorker.java:79)
at com.ch4process.acquisition.ScenarioWorker.call(ScenarioWorker.java:1)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

如您所见,此异常是在线程中引发的。

这是代码(稍微简化了一下):

public class ScenarioWorker implement Callable<Integer>
{
List<SignalValueEvent> eventList = new LinkedList<>();

boolean busy = false;

@Override
public Integer call() throws Exception
{
    try
    {
        while (true)
        {
            eventHandling();
            Thread.sleep(1000);
        }
    }
    catch (Exception ex)
    {
        // Redirects the exception to a custom class
    }
}

private void eventHandling()
{
    if (! busy)
    {
        while (eventList.size() > 0)
        {       
            SignalValueEvent event = eventList.get(0); // NullPointerException here according to stacktrace

            if(event.isTriggered()))
            {
                busy = true;
                doScenario(event);
            }
            deleteEvent();
        }
    }
}


private void deleteEvent()
{
    try
    {
        eventList.remove(0);
    }
    catch (Exception ex)
    {
        // Redirects the exception to custom class
    }
    finally
    {
        busy = false;
    }
}


@Override
public void SignalValueChanged(SignalValueEvent event)
{
    if (event.isValid())
    {
        eventList.add(event);
    }
}

[编辑:堆栈跟踪中的第 97 行是 SignalValueEvent event = eventList.get(0); ]

此类实现了一个接口(interface),该接口(interface)允许另一个类通过调用 SignalValueChanged 方法来通知它。

所以基本上我的 LinkedList 是在类的初始化时创建的,每当需要将事件放入列表时由外部类填充,并且调用方法在列表上循环以查看其中是否有任何内容。如果存在,则对其进行处理并删除该事件。

我已经对此进行了测试,我应该拥有 NPException 的唯一原因是我的列表是否等于 null...但我不会在我的代码中的任何地方这样做...

正如我所说,这段代码是 24/7 全天候工作的,在我启动应用程序将近一个半星期后,我遇到了这个错误。我缺少什么明显的东西吗?

非常感谢您阅读本文,如果您能帮助我,我将很高兴:)

最佳答案

NPE 不是因为您的列表为空——如果是,您的异常的根源将在 ScenarioWorker.java 第 97 行。相反,代码将其放入LinkedList,这表明 LinkedList 实现内部的某些东西被搞砸了——这是并发问题的一个巨大的危险信号。至于为什么,可能是一个线程在调用 SignalValueChanged 而另一个线程同时调用 eventHandling 的竞争。

您可以通过同步对eventList 的所有访问来解决它。最简单的方法可能只是将方法 SignalValueChangedeventHandling 标记为 synchronized

关于Java-链​​表 : Weird NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41428055/

相关文章:

java - GUI 在 EDT 上显示

java - 如何在 Java 中正确计算字符串的长度?

java - 在框架上绘图和 JLabel

java.lang.NullPointerException异常

java - 当字段不为空时抛出 nullpointerException

c - 如何在循环中创建节点并将它们插入链表

java - 在 IntelliJ Java 的代码样式中,我们如何将其设置为要求带注释的字段之间有空行,而在非带注释的字段之间没有空行

java - 服务帐户创建的文件夹不会出现在 Google Drive Web 应用程序中

python - 使用Python实现链表删除功能时出错

linked-list - 在我的 Rust 单链表中实现 .pop() 的更好方法是什么?