public class SousThread implements Runnable {
private int i;
public SousThread() {
this.i = 0;
}
@Override
public void run() {
while(true) {
System.out.println("I'm sousthread " + i++);
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class TestThread implements Runnable {
@Override
public void run() {
System.out.println("I'm thread");
SousThread st = new SousThread();
Thread td = new Thread(st);
td.start();
System.out.println("thread finished");
}
public static void main(String[] args) {
TestThread tt = new TestThread();
Thread td = new Thread(tt);
td.start();
System.out.println("main finished");
}
}
我试图在线程SousThread
中创建线程TestThread
。 SousThread
是无限的。
令我惊讶的是,我得到了以下结果:
I'm thread
main finished
thread finished
I'm sousthread 0
I'm sousthread 1
I'm sousthread 2
I'm sousthread 3
I'm sousthread 4
I'm sousthread 5
...
...
是否意味着方法main
已经完成而线程还没有完成?这可能吗?这样安全吗?如果没有,那么更好的方法是什么?
更新
因为像这样的代码在C ++中不起作用。所以我只想知道代码是否在Java中没有任何问题或任何风险。
答案 0 :(得分:1)
这是well documented,完全正常:
当Java虚拟机启动时,通常会有一个非守护程序线程(通常调用某个指定类的名为main的方法)。 Java虚拟机继续执行线程,直到发生以下任一情况:
- 已调用类Runtime的exit方法,安全管理器已允许退出操作。
- 非守护程序线程的所有线程都已死亡,无论是通过调用run方法返回还是抛出一个超出run方法传播的异常。 / LI>
在你的情况下,当主线程终止时(隐式地通过main()
返回),其他线程仍处于活动状态。除非您在某处调用System.exit()
或将其他线程设置为守护程序线程,否则JVM将继续运行,直到所有线程都已加入。
如果希望所有线程在主线程存在之前终止,则需要Thread.join()
它们。请注意,Runtime.exit()
非常严格地终止线程。线程是not interrupted nor are their finalizers called,所以这真的不安全。
答案 1 :(得分:1)
您在代码中所做的工作如下所述:
main
线程首先由JVM启动TestThread
由main
主题SousThread
由TestThread
这是否意味着方法main已完成而线程已完成 还没完呢?这可能吗?
是的,每个线程并行运行,main
线程先完成,然后TestThread
完成,但SousThread
线程仍然运行(因为无限{ {1}}循环)。
另外,您需要记住的另一点是您不能期望&保证哪个线程运行&首先完成(除非你运行无限循环),你可以看here开始并更多地了解线程。
答案 2 :(得分:0)
是的,这是可能的。如果希望终止线程,则应在线程上调用setDaemon方法。