我写了一个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()。我还不知道如何处理异常问题。
答案 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");
}
}
}
}