11
回答
java 父线程退出 子线程会退出么?
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   

在写一个springMVC 的应用中,一个请求涉及到逻辑比较复杂,耗时比较长,所以打算用线程来做,只简单的给请求返回成功接收。这样 如果在springMVC中启动一个线程来处理逻辑,这样的话。父线程执行完毕了,子线程会退出么??


求指教,如果不会,在那里的权威文档写过呢?

举报
yinhex
发帖于4年前 11回/7K+阅
共有11个答案 最后回答: 4年前

刚研究了一下linux的线程:我觉得java的线程跟pthread的非常相似。以前看资料也是看到java在linux的底层线程就是pthread。

如果使用过 fork() 系统调用,可能熟悉父进程和子进程的概念。当用 fork() 创建另一个新进程时,新进程是子进程,原始进程是父进程。这创建了可能非常有用的层次关系,尤其是等待子进程终止时。例如,waitpid() 函数让当前进程等待所有子进程终止。waitpid() 用来在父进程中实现简单的清理过程。

而 POSIX 线程就更有意思。您可能已经注意到我一直有意避免使用“父线程”和“子线程”的说法。这是因为 POSIX 线程中不存在这种层次关系。虽然主线程可以创建一个新线程,新线程可以创建另一个新线程,POSIX 线程标准将它们视为等同的层次。所以等待子线程退出的概念在这里没有意义。POSIX 线程标准不记录任何“家族”信息。缺少家族信息有一个主要含意:如果要等待一个线程终止,就必须将线程的 tid 传递给 pthread_join()。线程库无法为您断定 tid。

对大多数开发者来说这不是个好消息,因为这会使有多个线程的程序复杂化。不过不要为此担忧。POSIX 线程标准提供了有效地管理多个线程所需要的所有工具。实际上,没有父/子关系这一事实却为在程序中使用线程开辟了更创造性的方法。例如,如果有一个线程称为线程 1,线程 1 创建了称为线程 2 的线程,则线程 1 自己没有必要调用 pthread_join() 来合并线程 2,程序中其它任一线程都可以做到。当编写大量使用线程的代码时,这就可能允许发生有趣的事情。例如,可以创建一个包含所有已停止线程的全局“死线程列表”,然后让一个专门的清理线程专等停止的线程加到列表中。这个清理线程调用 pthread_join() 将刚停止的线程与自己合并。现在,仅用一个线程就巧妙和有效地处理了全部清理。

(摘自IBM网站的一篇文章)

来自:http://www.ibm.com/developerworks/cn/linux/thread/posix_thread1/

线程之间是忽略父子的关系的,都是平级的,这进程不同。

所以,虚拟机为主进程,在虚拟机进程出来的线程 都是同级的。

而Jvm进程在所有的非守护线程结束后,自己才会全部退出。所以,在java里父线程结束 不会影响到子线程的。


从问题本身来讲答案是肯定的,即父线程执行完毕后,子线程会退出。从下面的代码可以得出结论:

@Test
public void sub() {
    new Thread() {
        public void run() {
            new Thread() {
                public void run() {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("sub thread exit");
                }
            }.start();
            System.out.println("parent thread exit");
        }
    }.start();
}
但是你想要达到的效果可以实现,使用线程池就可以了,把逻辑复杂的部分包装成一个线程,然后提交到线程池执行。

--- 共有 3 条评论 ---
甘薯楼主没错,父线程退出,子线程不一定退出。 4年前 回复
mushui我错了,Junit害死人 4年前 回复
yinhex你的代码我还没有仔细研读,但是java 里面,父线程退出,子线程不一定会退出. 4年前 回复

线程分为守护线程和非守护线程,通过isDaemon()可以查看。

Java进程在所有的非守护线程结束后,会全部结束,所有守护线程都会停止。如果只是某个父线程结束,它产生的子线程不会受到影响。

一个线程是否是守护线程默认和他的父线程及ThreadGroup有关,但可以在start以前通过setDaemon()自行设置。

--- 共有 3 条评论 ---
yinhex回复 @逝水fox : 哈哈 java的并发我是真的不太想深入研究了。现在我主力的学习go的 协程 4年前 回复
逝水fox回复 @yinhex : 这些内容在JDK API文档Thread类里面有说的,系统点也可以看 Java并发编程实战 这本书, 4年前 回复
yinhex兄弟说的对头,不过你从哪里获得这些知识点的呢???我想确认一下 4年前 回复
public class TwoThreadDemo implements Runnable{

	/**
	 * @param args
	 */
	@Override
	public void run() {
		// TODO Auto-generated method stub
		for(int i = 0; i<10000; i++)
		{
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			String threadName = Thread.currentThread().getName();
			System.out.println(threadName+" is running");
		}
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(Thread.currentThread().getName()+" is running");
		Thread thread1 = new Thread(new TwoThreadDemo(),"Thread1");
		Thread thread2 = new Thread(new TwoThreadDemo(),"Thread2");
		thread1.start();
		thread2.start();
		System.out.println(Thread.currentThread().getName()+" is running");
		System.out.println("finsh");
	}
}
--- 共有 2 条评论 ---
yinhex这位兄弟又如何去证明 是父线程在等待子线程 呢??? 4年前 回复
loyal这不能证明主线程退出了,这只能证明当子线程没有退出时,主线程会等待子线程结束. 4年前 回复
上面就是证明 父线程退出了,子线程依然可以运行
--- 共有 1 条评论 ---
古月楼是的。在Java多线程中。如果子线程运行时间太长。主线程是不会等所有的子线程运行完毕后推出的。当然Callable有返回值的线程除外。有返回值的线程只要主线程不去get()。也是不会堵塞的。 4年前 回复
我测试过,好像子线程不会退出的,即便你把子线程设置为后台线程也不行。不知道原因
--- 共有 1 条评论 ---
逝水fox守护线程是要你人工exit()或者系统里面所有非守护线程都退出才退出,并不是只看父线程,还有setDaemon()只有在start以前设置才有用。 4年前 回复
顶部