0
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");
    }
}

I'm trying to create thread SousThread in thread TestThread. SousThread is infinite.

To my surprise, I get the result below:

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
...
...

Does it mean that the method main has finished whereas the thread hasn't finished yet? Is this possible? Is this safe? If not, what is the better way to do?

UPDATE

Because the code like this doesn't work in C++. So I just want to know if the code works without any problem or any risk in Java.

Gray
  • 115,027
  • 24
  • 293
  • 354
Yves
  • 11,597
  • 17
  • 83
  • 180
  • 1
    Better way to do *what*? "Is this possible?" Well, clearly. "Is this safe?" Safe in what way? – Kayaman Mar 24 '17 at 21:47
  • @Kayaman `main` has finished, but the thread which belongs to `main` hasn't finished. Doesn't it mean something to you? – Yves Mar 24 '17 at 21:49
  • Not particularly, but that's probably because I understand how threading works in Java. – Kayaman Mar 24 '17 at 21:50
  • @Kayaman So we can do like this or not? – Yves Mar 24 '17 at 21:50
  • You just did it, didn't you? – Kayaman Mar 24 '17 at 21:51
  • @Kayaman yes, I did and it seems that it works. But I want to make sure that all of threads should be terminated before `main` finished. – Yves Mar 24 '17 at 21:53
  • So you want your main thread to wait for the threads being finished? You can use for example `Thread.join()` for that. – Kayaman Mar 24 '17 at 21:54
  • @Kayaman yes you are right. :) Maybe I'm just shocked by java because the code doesn't work in C++. – Yves Mar 24 '17 at 22:05

3 Answers3

1

This is well documented and completely normal:

When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class). The Java Virtual Machine continues to execute threads until either of the following occurs:

  • The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
  • All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.

In your case, while the main thread has terminated (implicitly by main() returning), the other threads are still alive. Unless you call System.exit() somewhere or set the other threads to be daemon threads, the JVM will continue running until all of your threads have joined.

If you want all threads to terminate before the main thread exists, you need to Thread.join() them. Note that Runtime.exit() terminates threads quite harshly. Threads are not interrupted nor are their finalizers called, so this is really not safe.

Community
  • 1
  • 1
dhke
  • 15,008
  • 2
  • 39
  • 56
  • So my code hasn't any risk or any problem (except that JVM will take care of that infinite thread )? – Yves Mar 24 '17 at 22:10
  • @Yuhui Well, `SousThread` does not have reliable way of terminating at all, so I'd not say that. But that problem is not caused by returning from `main()`. – dhke Mar 24 '17 at 22:15
  • It's important to realize that daemon status of the threads is gotten from parent that spawned it. Since main is a non-daemon thread then the `TestThread` thread and the `SousThread` thread are also both non-daemon. You should use `thread.setDaemon(...)` before calling `start()` if you was specific behavior. – Gray Mar 24 '17 at 22:23
  • @Gray ... which still leaves the problems that daemon threads don't go down "nicely" on JVM exit, so I'd say that's best avoided, anyway. – dhke Mar 24 '17 at 22:28
  • No, there are good reasons to have daemon threads. See my answer here: http://stackoverflow.com/a/10298353/179850 – Gray Mar 25 '17 at 02:49
1

What you did in your code is explained below:

  1. main thread was initiated first by JVM
  2. TestThread was started by main thread
  3. SousThread was started by TestThread

Does it mean that the method main has finished whereas the thread hasn't finished yet? Is this possible?

Yes, each thread runs parallely and main thread finished first and then the TestThread finished, but the SousThread thread still runs (because of infinite while loop).

Also, one more point that you need to remember is that you can't expect & guarantee which thread runs & finishes first (unless you are running infinite loop), you can look here to start and understand more about threads.

Gray
  • 115,027
  • 24
  • 293
  • 354
Vasu
  • 21,832
  • 11
  • 51
  • 67
0

Yes, that's possible. If you want your thread to be terminated, you should invoke setDaemon method on the thread.

Farrandu
  • 371
  • 1
  • 7