java主线程结束和子线程结束之间的关系
(一)Main线程是个非守护线程,不能设置成守护线程。
这是因为,main线程是由java虚拟机在启动的时候创建的。main方法开始执行的时候,主线程已经创建好并在运行了。对于运行中的线程,调用Thread.setDaemon()会抛出异常Exception in thread "main" java.lang.IllegalThreadStateException。测试代码如下:
- public class MainTest
- {
- public static void main(String[] args)
- {
- System.out.println(" parent thread begin ");
- Thread.currentThread().setDaemon(true);
- }
- }
(二)Main线程结束,其他线程一样可以正常运行。
主线程,只是个普通的非守护线程,用来启动应用程序,不能设置成守护线程;除此之外,它跟其他非守护线程没有什么不同。主线程执行结束,其他线程一样可以正常执行。代码如下:
- public class ParentTest
- {
- public static void main(String[] args)
- {
- System.out.println("parent thread begin ");
- ChildThread t1 = new ChildThread("thread1");
- ChildThread t2 = new ChildThread("thread2");
- t1.start();
- t2.start();
- System.out.println("parent thread over ");
- }
- }
- class ChildThread extends Thread
- {
- private String name = null;
- public ChildThread(String name)
- {
- this.name = name;
- }
- @Override
- public void run()
- {
- System.out.println(this.name + "--child thead begin");
- try
- {
- Thread.sleep(500);
- }
- catch (InterruptedException e)
- {
- System.out.println(e);
- }
- System.out.println(this.name + "--child thead over");
- }
- }
- --程序运行结果如下:
- parent thread begin
- parent thread over
- thread2--child thead begin
- thread1--child thead begin
- thread2--child thead over
- thread1--child thead over
这样其实是很合理的,按照操作系统的理论,进程是资源分配的基本单位,线程是CPU调度的基本单位。对于CPU来说,其实并不存在java的主线程和子线程之分,都只是个普通的线程。进程的资源是线程共享的,只要进程还在,线程就可以正常执行,换句话说线程是强依赖于进程的。也就是说,线程其实并不存在互相依赖的关系,一个线程的死亡从理论上来说,不会对其他线程有什么影响。
(三)Main线程结束,其他线程也可以立刻结束,当且仅当这些子线程都是守护线程。
java虚拟机(相当于进程)退出的时机是:虚拟机中所有存活的线程都是守护线程。只要还有存活的非守护线程虚拟机就不会退出,而是等待非守护线程执行完毕;反之,如果虚拟机中的线程都是守护线程,那么不管这些线程的死活java虚拟机都会退出。测试代码如下:
- public class ParentTest
- {
- public static void main(String[] args)
- {
- System.out.println("parent thread begin ");
- ChildThread t1 = new ChildThread("thread1");
- ChildThread t2 = new ChildThread("thread2");
- t1.setDaemon(true);
- t2.setDaemon(true);
- t1.start();
- t2.start();
- System.out.println("parent thread over ");
- }
- }
- class ChildThread extends Thread
- {
- private String name = null;
- public ChildThread(String name)
- {
- this.name = name;
- }
- @Override
- public void run()
- {
- System.out.println(this.name + "--child thead begin");
- try
- {
- Thread.sleep(500);
- }
- catch (InterruptedException e)
- {
- System.out.println(e);
- }
- System.out.println(this.name + "--child thead over");
- }
- }
- 执行结果如下:
- parent thread begin
- parent thread over
- thread1--child thead begin
- thread2--child thead begin
在这种情况下,的确主线程退出,子线程就立刻结束了,但是这是属于JVM的底层实现机制,并不是说主线程和子线程之间存在依赖关系
java主线程结束和子线程结束之间的关系的更多相关文章
- Java主线程如何等待子线程执行结束(转)
工作中往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的产景, 这时候就需要使用线程了. 一个线程启动之后, 是异步的去执行需要执行的内容的, 不会影响主线 ...
- [Java][Android] 多线程同步-主线程等待全部子线程完毕案例
有时候我们会遇到这种问题:做一个大的事情能够被分解为做一系列相似的小的事情,而小的事情无非就是參数上有可能不同样而已! 此时,假设不使用线程,我们势必会浪费许多的时间来完毕整个大的事情.而使用线程的话 ...
- java主线程等待所有子线程执行完毕在执行(常见面试题)
java主线程等待所有子线程执行完毕在执行(常见面试题) java主线程等待所有子线程执行完毕在执行,这个需求其实我们在工作中经常会用到,比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个 ...
- Java中主线程如何捕获子线程抛出的异常
首先明确线程代码的边界.其实很简单,Runnable接口的run方法所界定的边界就可以看作是线程代码的边界.Runnable接口中run方法原型如下: public void run(); 而所有的具 ...
- c/c++中主线程退出,子线程也会退出
#include <windows.h> #include <process.h> /* _beginthread, _endthread */ #include <io ...
- .Net主线程扑捉子线程中的异常
首先看一段C#代码:运行后发现主线程通过try{}catch{}是不能扑捉子线程中的抛出来的异常. 代码 ); } public void run() { ...
- Java主线程等待所有子线程执行完毕再执行解决办法(转)
方法一: Thread.join()方法,亲测可行,thread.join()方法 Vector<Thread> ts = new Vector<Thread>(); for ...
- Java多线程之以7种方式让主线程等待子线程结束
记一次主线程等待子线程结束的多种方法的学习 在学习多线程时,最开始遇到的问题其实是"计算子线程运行时间",写到最后发现本文和标题更为符合,但是仍然基于问题:"在主线程中获 ...
- Java主线程等待子线程、线程池
public class TestThread extends Thread { public void run() { System.out.println(this.getName() + &qu ...
随机推荐
- C++总的const使用说明
C++总的const使用说明 1. const修饰类成员变量 程序: #include <iostream> using namespace std; class A { public: ...
- struts2 跳转类型 result type=chain、dispatcher、redirect(redirect-action)
dispatcher 为默认跳转类型,用于返回一个视图资源(如:jsp) Xml代码 : <result name="success">/main.jsp</re ...
- MVC4 项目开发日志(1)
最近一直在定义一个功能全面,层次结构分明的框架.一边学习一边应用.
- Checkpoint--在Tempdb上的特殊性
由于Checkpoint的目的是为减少数据库恢复时间,而每次实例重启都会创建新的tempdb,而不需要恢复,因此checkpoint在Tempdb上行为与其他用户数据库上略微不同. 1. 系统引发的c ...
- System.IO.FileLoadException:“混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。”
解决方案: 在app.config新增如下配置节: <?xml version="1.0"?> <configuration> <startup us ...
- Python廖雪峰学习笔记——操作文件和目录
查看当前目录的绝对路径: >>>os.path.abspath('.') # 在某个目录下创建一个新目录, # 首先把新目录的完整路径表示出来: >>> os.pa ...
- FastAdmin 前端页面传参
如果我们需要自己在控制器中透传数据到JS中去,则可以使用控制器的assignconfig方法来透传,使用如下 $this->assignconfig('demo', ['name'=>'名 ...
- nodejs 像 C 语言那样输出当前代码的行数
http://stackoverflow.com/questions/11386492/accessing-line-number-in-v8-javascript-chrome-node-js Ob ...
- poj3026
Borg Maze Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12952 Accepted: 4227 Descri ...
- jvm(1)类的加载(三)(线程上下文加载器)
简介: 类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的. Java Applet 需要从远程下载 Java 类文件到浏览器中并执行. 现在类加载器在 ...