Reputation: 595
I tested a multi-thread program in JUnit and main function, source code as follows:
public class TestDaemon {
@Test
public void test() {
Thread thread = new Thread(() -> {
try {
Thread.sleep(1000);
System.out.println("hello");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// default false
thread.setDaemon(false);
thread.start();
}
public static void main(String[] args) {
Thread thread = new Thread(() -> {
try {
Thread.sleep(1000);
System.out.println("hello");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// default false
thread.setDaemon(false);
thread.start();
}
}
It didn't print hello
string in the JUnit test example.
In the main function example, it could print hello
in the console, but when I set the thread.setDaemon(true)
, it also can't print hello
.
I know this is related to
Daemon thred
andUser thread
, but I don't know how to explain it.
Upvotes: 0
Views: 154
Reputation: 595
We can analyze the source code of JUnit, part of junit.textui.TestRunner
as follows:
public static final int SUCCESS_EXIT = 0;
public static final int FAILURE_EXIT = 1;
public static final int EXCEPTION_EXIT = 2;
...
public static void main(String args[]) {
TestRunner aTestRunner = new TestRunner();
try {
TestResult r = aTestRunner.start(args);
if (!r.wasSuccessful()) {
System.exit(FAILURE_EXIT);
}
System.exit(SUCCESS_EXIT);
} catch (Exception e) {
System.err.println(e.getMessage());
System.exit(EXCEPTION_EXIT);
}
}
/**
* Returns whether the entire test was successful or not.
*/
public synchronized boolean wasSuccessful() {
return failureCount() == 0 && errorCount() == 0;
}
/**
* Gets the number of detected failures.
*/
public synchronized int failureCount() {
return fFailures.size();
}
/**
* Gets the number of detected errors.
*/
public synchronized int errorCount() {
return fErrors.size();
}
In this source code, we can conclude that the TestRunner excutes the Unit Test method
, no need to wait it finish their tasks, then calls System.exit()
method, so that terminates the program. So, it couldn't print hello
in the console.
In the main function, because the new thread is not daemon thread, the main program will wait it finishing their tasks, then teminates the program. So,hello
string could be seen in the console.
Upvotes: 0
Reputation: 119
A daemon thread is a thread that does not prevent the JVM from exiting when the program finishes but the thread is still running. An example for a daemon thread is the garbage collection.
When you run your code from main it creates both beans, thus two threads - daemon and non-daemon. As long as non-daemon thread is running, your application won't exit. So it works.
It's different when run from JUnit. As soon as JUnit test method completes (and it completes immediately after the Spring context is up), JUnit assumes your tests are done. Thus it kills all your threads and basically the whole JVM.
Remember your Waitor1 bean spawns a background thread which JUnit doesn't care about. As soon as you leave @Test method JUnit will just stop everything.
Upvotes: 3