java线程执行顺序

时间:2017-03-24 21:44:56

标签: java multithreading

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中创建线程TestThreadSousThread是无限的。

令我惊讶的是,我得到了以下结果:

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中没有任何问题或任何风险。

3 个答案:

答案 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)

您在代码中所做的工作如下所述:

  1. main线程首先由JVM启动
  2. TestThreadmain主题
  3. 启动
  4. SousThreadTestThread
  5. 启动
      

    这是否意味着方法main已完成而线程已完成   还没完呢?这可能吗?

    是的,每个线程并行运行main线程先完成,然后TestThread完成,但SousThread线程仍然运行(因为无限{ {1}}循环)。

    另外,您需要记住的另一点是您不能期望&保证哪个线程运行&首先完成(除非你运行无限循环),你可以看here开始并更多地了解线程。

答案 2 :(得分:0)

是的,这是可能的。如果希望终止线程,则应在线程上调用setDaemon方法。