首页 文章

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

提问于
浏览
0

我写了一个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 回答

  • 2

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

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

    这意味着你 are 确实从 run 方法调用了 stop . 那's wrong. It worked with no exception because then you didn' t进入了阻止区 . 你需要在catch块中写入 break; 以打破while循环 .

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

  • 1

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

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

相关问题