在多个线程上使用 Thread.join 出现 NullPointer 异常

发布于 2024-11-05 18:30:51 字数 764 浏览 0 评论 0原文

我的 Java 程序之一遇到以下问题。 我正在尝试根据主程序在文件系统上找到的内容来启动多个线程。 它的工作方式非常经典: - 第一个循环:实例化、存储在本地数组中并启动一个新线程 - 第二个循环:使用“.join()”方法等待所有线程

在执行时,我在“.join()”上收到 NullPointerException。此异常是由启动的第三个线程引发的(因为它在第 2 个线程之前完成)

这是我的代码示例:

PackageManager[] myRootManagers = new PackageManager[myCCDirs.size()];
int i = 0;
for (PkgDescriptor descriptor : myCCDirs) {
    ...
    // --- instantiate new ROOT manager
    myRootManagers[i] = new PackageManager(getConfig(), loggerPac, descriptor);
    // --- start it
    myRootManagers[i].start();
}

for (PackageManager packageManager : myRootManagers) {
    try {
        packageManager.join();
    }
    catch (InterruptedException e) {
        loggerPac.error("...");
    }
}

有人知道为什么会发生此异常吗?

I have the following issue with one of my Java programs.
I'm trying to launch several threads depending on what my main program find on the file system.
The way it works is quite classic:
- First loop: instantiate, store in a local array and start a new thread
- Second loop: wait all of thread with '.join()' method

At execution i get a NullPointerException on the '.join()'. This exception is thrown by the 3rd thread launched (because it finishes before the 2 first one)

This is an example of my code:

PackageManager[] myRootManagers = new PackageManager[myCCDirs.size()];
int i = 0;
for (PkgDescriptor descriptor : myCCDirs) {
    ...
    // --- instantiate new ROOT manager
    myRootManagers[i] = new PackageManager(getConfig(), loggerPac, descriptor);
    // --- start it
    myRootManagers[i].start();
}

for (PackageManager packageManager : myRootManagers) {
    try {
        packageManager.join();
    }
    catch (InterruptedException e) {
        loggerPac.error("...");
    }
}

Does someone know why this exception occurs ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

栖迟 2024-11-12 18:30:51

确保第一个循环中的所有 i 覆盖 myRootManagers 数组中的所有有效不确定因素。

请注意,您应该在第一个 for 循环的 end 中增加 i,因为数组 indecies 是从 0 开始的。:

int i = 0;
for (PkgDescriptor descriptor : myCCDirs) {
    ...
    // --- instantiate new ROOT manager
    myRootManagers[i] = new PackageManager(getConfig(), loggerPac, descriptor);
    // --- start it
    myRootManagers[i].start();

    i++;   // <-----------------------------------
}

作为调试步骤,我会

System.out.println(Arrays.toString(myRootManagers));

在第一个循环之后 添加,断言不存在 null 引用。

Make sure all i in the first loop covers all valid indecies in the myRootManagers array.

Note that you should increment i in the end of the first for loop, since array indecies are 0-based.:

int i = 0;
for (PkgDescriptor descriptor : myCCDirs) {
    ...
    // --- instantiate new ROOT manager
    myRootManagers[i] = new PackageManager(getConfig(), loggerPac, descriptor);
    // --- start it
    myRootManagers[i].start();

    i++;   // <-----------------------------------
}

As a debugging step, I would add

System.out.println(Arrays.toString(myRootManagers));

after the first loop, to assert that there are no null references left.

守不住的情 2024-11-12 18:30:51

这对我来说似乎很奇怪,除非你隐藏了重要的部分:

for (PkgDescriptor descriptor : myCCDirs) {
    ...
    // --- instantiate new ROOT manager
    myRootManagers[i] = new PackageManager(getConfig(), loggerPac, descriptor);
    // --- start it
    myRootManagers[i].start();
}

你迭代 myCCDirs 但初始化 myRootManagers 对象,也许你没有增加 i

This seems odd to me unless you hidden the important part:

for (PkgDescriptor descriptor : myCCDirs) {
    ...
    // --- instantiate new ROOT manager
    myRootManagers[i] = new PackageManager(getConfig(), loggerPac, descriptor);
    // --- start it
    myRootManagers[i].start();
}

You iterate over myCCDirs but initialize myRootManagers objects, maybe you didn't increment i?

琉璃繁缕 2024-11-12 18:30:51

如果在另一个线程中删除 myCCDirs,也可能会发生这种情况。

PackageManager[] myRootManagers = new PackageManager[myCCDirs.size()]; // size is 3
int i = 0;
for (PkgDescriptor descriptor : myCCDirs) { // size is now 2 so the last field is not set.

This could also happen if a myCCDirs is removed in another thread.

PackageManager[] myRootManagers = new PackageManager[myCCDirs.size()]; // size is 3
int i = 0;
for (PkgDescriptor descriptor : myCCDirs) { // size is now 2 so the last field is not set.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文