有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java NullPointerException在实例化数组的所有成员后枚举数组时发生?

我正在编写一段涉及线程的代码,我已经设置了以下for循环来实例化它们:

for (Buyer buyer : buyers) {
    isPrime = (rand.nextInt(10) + 1 < 3);
    buyer = new Buyer(warehouse,
                      isPrime,
                      "buyer" + ++i);
    buyer.start();
    System.out.println("started buyer: " + i);
}

之后,我将实例化一些其他线程,然后再次加入这些买方线程,等待程序完成:

System.out.println("Joining buyers. ");
for (Buyer buyer : buyers) {
    buyer.join();
    System.out.println("Joining thread: " + buyer.getName());
}

当我运行我的程序时,我在下面的一行得到1个NullPointerException:buyer.join();所有线程都完成了执行,但没有一个线程似乎想在该点加入。这是怎么回事

以下是买家线程的代码:

import java.util.Random;

public class Buyer extends Thread{
    private int packsBought = 0;
    private boolean isPrime;
    private Random rand;
    private Warehouse warehouse;

    public Buyer(Warehouse warehouse, Boolean isPrime, String name) {
        super(name);
        this.isPrime = isPrime;
        this.rand = new Random();
        this.warehouse = warehouse;
    }
    
    public void run() {
        while(this.packsBought < 10) {
            try {
                Thread.sleep(this.rand.nextInt(49) + 1);
            } catch (InterruptedException ex) {
                
            }
            Order order = new Order(this.rand.nextInt(3)+ 1, 
                                    this, 
                                    this.isPrime);
            this.warehouse.placeOrder(order);
        }
        System.out.println("Thread: " + super.getName() + " has finished.");
    }

    public int getPacksBought() {
        return this.packsBought;
    }

    public void setPacksBought(int packsBought) {
        this.packsBought = packsBought;
    }

    public boolean isPrime() {
        return isPrime;
    }  
}

共 (1) 个答案

  1. # 1 楼答案

    问题在于:

    for (Buyer buyer : buyers) {
        isPrime = (rand.nextInt(10) + 1 < 3);
        buyer = new Buyer(warehouse,          // < - this is wrong 
                          isPrime,
                          "buyer" + ++i);
        buyer.start();
        System.out.println("started buyer: " + i);
    }
    

    您并没有真正初始化列表buyers中的元素。这:

    buyer = new Buyer(warehouse,
                              isPrime,
                              "buyer" + ++i);
    

    不会更改保存在列表buyers上的引用。是的,您将创建并启动一组线程。但在:

    System.out.println("Joining buyers. ");
    for (Buyer buyer : buyers) {
        buyer.join();
        System.out.println("Joining thread: " + buyer.getName());
    }
    

    您没有对已创建并启动的线程(买家)调用join。让你得到一个NPE

    buyer.join();
    

    是因为您已经用null初始化了买家列表,认为可以在循环中初始化:

       for (Buyer buyer : buyers) {
            isPrime = (rand.nextInt(10) + 1 < 3);
            buyer = new Buyer(warehouse,
                              isPrime,
                              "buyer" + ++i);
            buyer.start();
            System.out.println("started buyer: " + i);
        }