主线程Main先结束还是子线程先结束?
程序员文章站
2022-06-10 23:33:55
...
今天在复习并发基础的时候,发现一个很有意思的问题,到底是主线程Main先结束呢,还是子线程先结束呢?这个主要分为两种情况,让我们来看一下。
情况一:没有设置子线程为守护进程
public class Thread3 {
public static void main(String[] args) throws InterruptedException {
//获得主线程
Thread curThread = Thread.currentThread();
//创建10个线程
for(int i = 0;i < 10; i++) {
//后一个线程需要等待前一个线程执行完才能执行下一个线程
Thread thread = new Thread(new Thread4(curThread));
thread.start();
curThread = thread;
}
}
}
//实现了Runnable接口
class Thread4 implements Runnable {
private Thread curThread;
//初始化
public Thread4(Thread curThread) {
this.curThread = curThread;
}
@Override
public void run() {
try {
//join方法使得后一个线程需要等待前一个线程执行完才能执行下一个线程
curThread.join();
System.out.println(curThread.getName() + " terminated");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- 这里的主要思想是在主线程中创建10个子线程,每一个子线程都需要等待前一个子线程执行完才能执行下一个线程。
- 从输出结果可以看到,时主线程先结束,然后其他子线程继续运行的。所以可以说明主线程也是普通的用户线程而已。
- 这样其实是很合理的,按照操作系统的理论,进程是资源分配的基本单位,线程是CPU调度的基本单位。对于CPU来说,其实并不存在java的主线程和子线程之分,都只是个普通的线程。进程的资源是线程共享的,只要进程还在,线程就可以正常执行,换句话说线程是强依赖于进程的。也就是说,线程其实并不存在互相依赖的关系,一个线程的死亡从理论上来说,不会对其他线程有什么影响。
情况二:设置子线程为守护进程
public class Thread3 {
public static void main(String[] args) throws InterruptedException {
//获得主线程
Thread curThread = Thread.currentThread();
//创建10个线程
for(int i = 0;i < 10; i++) {
//后一个线程需要等待前一个线程执行完才能执行下一个线程
Thread thread = new Thread(new Thread4(curThread));
thread.setDaemon(true);
thread.start();
thread.sleep(100);
curThread = thread;
}
}
}
//实现了Runnable接口
class Thread4 implements Runnable {
private Thread curThread;
//初始化
public Thread4(Thread curThread) {
this.curThread = curThread;
}
@Override
public void run() {
try {
//join方法使得后一个线程需要等待前一个线程执行完才能执行下一个线程
curThread.join();
System.out.println(curThread.getName() + " terminated");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- 这个代码和上面的代码几乎一样,区别在于main方法中加入和设置守护进程,并且睡觉100毫秒。
- 这里有一点需要注意的是,主线程不能设置为守护进程,否则会报错:Exception in thread “main” java.lang.IllegalThreadStateException
- 这里从输出结果可以看到主线程结束了,其他子线程也随之结束了,并没有输出所有的子线程。
推荐阅读