Java:守护进程:thread.join()没有完成,当在一个线程中抛出异常时

时间:2012-05-30 11:45:20

标签: java multithreading exception daemon runnable

我写了一个Java守护进程(一个实现守护进程和Runnable的类),现在我遇到了以下问题:

在init()中我创建了一个新线程。 Thread thread = new Thread(this); 在start()中我启动新线程。 thread.start()。 在运行中我做了很多不同的事情......然后发生异常。 (在我的例子中:NullPointerException。)。

现在发生的是我在run()中捕获异常并调用stop()。在那里我调用thread.join(),但这永远不会完成,并且不会抛出InterruptedException。我该如何解决这个问题?

在run()中,我在while循环中做了一些事情

private Thread thread;

public void init() {
    // if init is successful: this.thread = new Thread(this);
    // if init is not successful: call stop()
}

public void run() {
  try{
  // do something
  while (!this.stopping)
  {
      // do somthing
  }
  } catch (Exception e) {
      //do something and then call stop()
  }
}

public void stop() {
    this.stopping = true;
    thread.join(); // catch InterruptedException if it did not work
    // do some more things
}

这就是引发异常的地方。停止是易失性的,一旦调用停止,我就将其设置为true。

谢谢: - )


我得到了很多答案,但我仍然没有解决这个问题。每个人都说我不应该在我的run()或init()方法中手动调用stop()。我的问题是,当init()或run()发生异常时,我想真正停止该程序。完成它,以便程序不再运行。我不知道如何在不调用stop()的情况下实现这一点。只需等待run()完成就不起作用,因为它会停止然后永远不会调用stop()。我还不知道如何处理异常问题。

3 个答案:

答案 0 :(得分:2)

调用stop很好。人们警告你不要拨打Thread.stop(),你没有这样做。你 做的是在你想要加入的同一个线程上调用join - 这当然会导致死锁。

catch (Exception e) {
  //do something and then call stop()
}

这意味着您确实确实从stop方法调用了run。那是错的。它没有任何例外,因为那时你没有进入catch-block。你需要在catch块中写入break;以打破while循环。

顺便说一句,你根本不需要Thread的引用 - 这只是令人困惑的事情。如果您需要访问正在执行Thread方法的run实例,则可以致电Thread.currentThread()

答案 1 :(得分:1)

你永远不应该叫停。只是从运行返回或从运行中抛出异常,线程将自行停止。 Thread.join是从某个想要等待守护程序线程完成的线程调用的。例如,如果主线程收到要关闭的消息,它可能会发信号通知守护进程停止(不是通过调用stop),然后使用join来等待守护进程实际停止。有一个教程here

答案 2 :(得分:1)

很难确切知道什么是错误的,因为你的例子仍然只是一些代码。我附上了几乎可以写的最简单的多线程程序。主线程每100毫秒打印一次“main”。另一个线程每100毫秒打印一次“其他”直到停止。主线程在10次迭代后停止另一个线程。你能解释一下你希望你做的这个程序不能做什么吗?我们可以改变它,直到它这样做。

public class Main {

    private Thread thread;
    private Other other;

    public static void main(String args[]) throws InterruptedException {
        Main main = new Main();
        main.run();
    }

    public void run() {
        other = new Other();
        thread = new Thread(other);
        thread.start();
        for (int i = 0; i < 10; i++) {
            System.out.println("main");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                System.out.println("interrupted waiting for sleep in main");
            }
        }
        stop();
    }

    public void stop() {
        other.stopping = true;
        try {
            thread.join();
        } catch (InterruptedException e) {
            System.out.println("interrupted waiting for other to join main");
        }
    }

}

class Other implements Runnable {

    volatile boolean stopping;

    @Override
    public void run() {
        while (!stopping) {
            System.out.println("other");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                System.out.println("interrupted waiting for sleep in other");
            }
        }
    }

}