JAVA主线程结束和子线程结束之间的关系
- main线程是一个非守护线程,不能设置成守护线程
main线程是由java虚拟机在启动额时候创建的。mian方法开始执行的时候,主线程已经创建好并运行了。
public static void main(String[] args) {
System.out.println("parent is begin");
Thread.currentThread().setDaemon(true);
}
输出:
parent is begin
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.setDaemon(Thread.java:1359)
测试可得,运行中的主线程,调用setDaemon(true);会抛异常。
- mian线程结束,其他线程一样可以运行
主线程只是一个普通的非守护线程,用来启动应用程序,不能设置成守护线程
class Children extends Thread{
private String name;
public Children(String name){
this.name = name;
}
@Override
public void run(){
System.out.println(this.name + "---chrild thread begin");
try{
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.println(this.name + "---chrild thread end");
}
}
public class DPLeecode {
public static void main(String[] args) {
System.out.println("parent is begin");
Children child1 = new Children("Thread1");
Children child2 = new Children("Thread2");
child1.start();
child2.start();
System.out.println("parent is end");
// Thread.currentThread().setDaemon(true);
}
}
控制台:
parent is begin
Thread1---chrild thread begin
parent is end
Thread2---chrild thread begin
Thread2---chrild thread end
Thread1---chrild thread end
按照操作系统的理论,进程是资源分配的基本单位,线程是CPU调度的基本单位。对于CPU来说,不存在JAVA的主线程和子线程,都是普通的线程。进程的资源是线程共享的,只要进程还在,线程就可以正常运行,同一进程下的线程共享全局变量、静态变量等数据。线程是强依赖与进程的,因为他需要环境呀。但是,线程与线程之间并不存在依赖关系,一个线程的结束理论上说并不会对其他线程有什么影响
- main线程结束,其他线程也可以立刻结束,当且仅当这些子线程都是守护线程
守护线程:可以当做是一个特殊的用户线程,主要用来服务于用户线程,不需要上层逻辑介入(eg:Java垃圾回收线程就是一个典型的守护线程)
JAVA虚拟机退出的时机(进程结束):虚拟机中所有存活的线程都是守护线程。只要还有存活的非守护线程虚拟机就不会退出,而等待非守护线程执行完毕。只要虚拟机剩下的都是守护线程,那么JAVA虚拟机不会管这些线程的死活,都会退出。
// 将上述子线程设置成守护线程
child1.setDaemon(true);
child2.setDaemon(true);
控制台:
parent is begin
Thread1---chrild thread begin
Thread2---chrild thread begin
parent is end
这种情况下,主线程已经退出了,身为守护线程的子线程立马结束。(属于jvm底层实现机制)