0

我写了一个 Java Daemon(一个实现 Daemon 和 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() 永远不会被调用。我还不确定如何处理异常问题。

4

3 回答 3

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().

于 2012-05-30T12:06:27.577 回答
1

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

于 2012-05-30T12:04:20.673 回答
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");
            }
        }
    }

}
于 2012-06-01T01:33:13.900 回答