【问题标题】:Does a process dies when the thread it created dies?当它创建的线程死亡时,进程是否会死亡?
【发布时间】:2020-12-02 05:21:10
【问题描述】:

我在 Java 中有一个具有 main() 函数的类。我们称它为 A。还有另一个类 B 实现了 Runnable 接口。在 A 类的 main 函数中,我创建了一个 B 类的线程,该线程将开始执行其逻辑。

现在,如果我们说因为某些错误,B 类的线程就死了。那么进程A会随之死亡吗?如果不是,当 B 类的线程死亡时,我们如何让进程 A 死亡。

反之亦然,比如如果进程 A 死了,那么 B 类的线程会随之死去吗?如果不是怎么让它死?

【问题讨论】:

标签: java multithreading process


【解决方案1】:

您的问题是关于如何捕获子线程的异常并在父线程中引发它。

从技术上讲,与其他答案一样,子线程中的中断确实在父线程中引发异常之间没有关系。

public static void main(String[] args){
 
  Thread child = new Thread(){
    public void run () {
            try {
                Object obj = null;
                String s = obj.toString(); //this will throw NullPointer
            } catch (NullPointerException e) {
                throw new RuntimeException("Hoping this reaches the parent! as NPE but it wont", e);
            }
        }
  };
  child.start();
}

但是,请回答您关于如何去做的问题。您可以使用Future<?> 并让RunnableCallable 执行等效操作并查看Future Result 的值

这是一个可以调用doSomething()的例子:

void doSomething(){
  Object s = null;
  System.out.println("You want to do something here!" +  s.toString()); // This will throw NPE
}

现在假设您想在单独的线程中运行它并捕获异常

ExecutorService executor = Executors.newFixedThreadPool(1);
Future result = pool.submit(this::doSomething());
try {
   result.get();
}catch (ExcecutionException e){
  e.printStackTrace(); //will show null pointer exception 
}

现在,在与 threadPool 不同的线程中运行的函数将引发执行异常,您可以选择在主/父线程中捕获该异常,并针对该故障执行您喜欢的操作。

希望这会有所帮助!


更新:

为什么从子线程中杀死父线程是不好的做法?

从线程外部终止任何线程是一个非常糟糕的主意。这是因为终止线程不知道目标在做什么以及它是否在“安全”点终止。例如,您可能正在编写输出、进行计算或其他任何事情。 ref.1

关于为什么你甚至应该停止/杀死/终止整个 JVM,也从来没有真正好的候选者。除非在我不断掌握 Java 和核心概念的过程中,我从来不需要处理杀死父进程的子进程。

只是为了详细说明,具体来说,实际上没有“子”线程或“父”线程的概念。 JVM 甚至也不跟踪哪个线程创建了哪个线程。

它主要基于线程组,例如。 “groupA”和“groupB”,只有一个“groupA”创建了“groupB”,JVM知道并跟踪。

如果你真的想停止 JVM。只需拨打System.exitref.2

考虑看看这个question

【讨论】:

  • 我不想在父进程中捕获异常。如果我在子进程中遇到任何异常,我希望父进程死掉。我检查了当孩子发生异常时,如果我们记录异常然后使用 System.exit(),它会杀死父母和孩子。这是一个好方法吗?还是会有什么后果?
  • 您可以在父进程中捕获异常,然后执行System.exit(),这是理想的方式。您不应该从子线程中杀死父线程。这是一个糟糕的赞美。
  • 你能解释清楚为什么从孩子那里杀死父母是不好的做法吗?或者你只是指向一些资源。这对我会有帮助。谢谢。
【解决方案2】:

没有;线程和启动它的线程之间实际上是零关系。它们对彼此没有任何影响。线程也与进程没有任何关系(从 ProcessBuilder 或 Runtime.exec 开始,与线程没有关系)。

【讨论】:

  • 您的断言“线程与进程没有 [no] 关系”可能会误导新手。你这么说是因为java.lang.Thread 类和java.lang.Process 类之间没有关系。但是,Thread 实例不是线程,Process 实例不是进程,并且在操作系统的上下文中(与讨论某个单一的 Java 程序相反)之间通常存在非常紧密的关系线程和进程。
  • 这个问题上的“java”标签有很多上下文。如果有人想通过从上下文中删除它来误解这个答案,我认为我们可以将责任完全放在读者身上。
  • 我不是在谈论更了解的人。我说的是那些来到这个网站寻求知识或寻求解决问题的人。我在这个网站上看到了数百个问题,这些问题正是因为 OP 在程序中创建和启动()Thread 实例,但他们实际上并不了解 thread 实际上是什么是。
  • 是的,如果这些人没有根据标签了解上下文,那么他们注定要失败。
猜你喜欢
  • 1970-01-01
  • 2018-02-22
  • 2018-05-15
  • 1970-01-01
  • 2011-12-09
  • 2014-06-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多