>source

나는 스레드와 관련된 code를 작업 중이며 모두 인스턴스화하기 위해 다음 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 ();모든 스레드가 실행을 마쳤지만 그 중 어떤 스레드도 그 시점에서 조인하려는 것 같습니다. 여기서 무슨 일이 일어나고 있습니까?

다음은 구매자 스레드의 code입니다.

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

    문제는 다음과 같습니다.

    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);
    }
    

    목록에서 요소를 실제로 초기화하지 않습니다.구매자. 이:

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

    목록에 저장된 참조는 변경되지 않습니다.구매자. 예, 여러 스레드를 만들고 시작합니다. 하지만 :

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

    생성하고 시작한 스레드 (구매자)에 대해 조인을 호출하지 않습니다. 그리고 NPE를 받으려면

    buyer.join();
    

    구매자 목록을 초기화했기 때문입니다.없는, 루프에서 초기화 할 수 있다고 생각합니다.

     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);
        }
    
  • 이전 c# : 저장하려면 전체 경로가 필요한 Visual Studio 통합 SQL 데이터베이스
  • 다음 git : 다른 분기에서 하나의 파일 만 가져 오는 방법