java - 对同一类中方法的无参数调用产生 NullPointerException

标签 java android multithreading nullpointerexception synchronized

我已经看到了很多奇怪的错误,但这次,我完全被难住了。尝试调用同一类中的方法时出现 NullPointerException。

首先,一些代码。让我们从违规行开始。当然,该方法比这更长,但这是它的开始以及所有相关的内容:

protected synchronized void checkTransfers() {
    if (isPaused())
        return;
}

isPaused 是一个简单的 getter 方法:

protected boolean isPaused() {
    return paused.get();
}

为了完整起见:

protected AtomicBoolean paused = new AtomicBoolean(false);

现在的问题是这段代码大约有 50% 的运行时间,它只是在 if (isPaused()) 行上抛出一个 NullPointerException,这对我来说毫无意义。 checkTransfers() 方法与 isPaused() 在同一个类中。我的同事试图通过提及问题可能出在所涉及的多线程中来帮助我,例如,如果另一个线程获得了 CPU 时间并删除了它对该对象的引用,但该对象永远不会在我的代码中的任何地方丢失其引用。另外:一旦 NPE 触发,this 仍然正确定义。

堆栈跟踪如下:

main@830013674640" prio=5 runnable java.lang.Thread.State: RUNNABLE at com.omines.android.communicationmanager.CommunicationManager.checkTransfers(CommunicationManager.java:125) at com.omines.android.communicationmanager.DownloadTask.onPostExecute(DownloadTask.java:105) at com.omines.android.communicationmanager.DownloadTask.onPostExecute(DownloadTask.java:20) at android.os.AsyncTask.finish(AsyncTask.java:602) at android.os.AsyncTask.access$600(AsyncTask.java:156) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:4945) at java.lang.reflect.Method.invokeNative(Method.java:-1) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) at dalvik.system.NativeStart.main(NativeStart.java:-1)

checkTransfers() 中的第 125 行是上面的 if 语句。

有谁知道什么会导致这样的行为?

最佳答案

是的,经过了一些邪恶的调试,但我似乎找到了问题所在。发布它以防它以后可以帮助其他人。

首先,您需要进一步了解我的方法。这是完整的:

protected synchronized void checkTransfers() {
    if (isPaused())
        return;
    while (transferQueue.peek() != null && (transferQueue.peek().priority == PRIORITY_URGENT ||
            (transferSemaphore.availablePermits() > maxConcurrentTransfers)))
    {
        CommunicationTask ct = transferQueue.poll();
        if (ct != null)
        {
            if (ct instanceof DownloadTask)
                currentlyDownloading.add((DownloadTask)ct);
            ct.execute();
        }
    }
}

我发现它不会在方法开始时立即抛出异常。事实证明,在异常发生之前,它会运行整个方法一次,然后调试器不会退出它,而是跳到方法的第一行并抛出 NullPointerException。

有了手头的工作,我发现只要执行的不是 DownloadTask 而是 UploadTask,就会发生这种情况。事实证明,我所有的 DownloadTasks 都知道它们的调用 Activity,以便它们可以显示进度对话框,但 UploadTask 总是被传递 null 而不是对调用者的引用。在旧版本的代码中这很好,但在最近的一些更改之后,显然它成为了一个问题。

我仍然不确定为什么每当我的任务试图访问对其调用 Activity 的不存在引用时我没有得到异常,但显然在看似无关的代码中触发异常是正常行为.

感谢您花时间阅读我的问题并尝试提供帮助。我希望至少我的回答对其他人有帮助。

关于java - 对同一类中方法的无参数调用产生 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18314585/

相关文章:

c# - 为什么 C# 中没有声明性不变性?

java - 通过 USB 将数据发送到 Android 应用程序

java - 从postgresql中批量插入的行中检索序列号

java - 日期选择器对话框在 fragment 中不起作用

java - ConcurrentHashMap 作为具有同步的单例缓存

android - 有什么方法可以从 .c 和 .h 文件生成 JNI 文件?

java - C#相当于Java的FloatBuffer/ShortBuffer?

java - "& 0xFF"和 ">>>"移位有什么作用?

Winforms 在单独的线程中执行代码

java - 运行 future 回调的参与者的线程安全