Let's use our new class, AThread, to demonstrate the behavior we have described. Here is the code we are going to run first:
Thread thr1 = new AThread(1, 4);
thr1.start();
Thread thr2 = new AThread(11, 14);
thr2.setDaemon(true);
thr2.start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Main thread exists");
In the preceding code, we create and immediately start two threads – a user thread, thr1, and a daemon thread, thr2. Actually, there is a user thread called main too, so we run two user threads and one daemon thread. Each of the child threads is going to print the incremented number four times, pausing for 1 second after each print. This means that each thread will be running for 4 seconds. The main thread will pause for 1 second too, but one time only, so it will run for approximately 1 second. Then, it prints Main thread exists and exists. If we run this code, we will see the following output:
We execute this code on one shared CPU, so, although all three threads are running concurrently, they can only use CPU sequentially. Therefore, they cannot be run in parallel. On a multicore computer, each thread may be executed on a different CPU and the output may be slightly different, but not by much. In any case, you would see that the main thread exits first (after approximately 1 second) and the child threads run until completion, each for approximately 4 seconds in total.
Let's make user thread run for only 2 seconds:
Thread thr1 = new AThread(1, 2);
thr1.start();
The result is:
As you can see, the daemon thread did not run the full course. It managed to print 13, probably only because it had sent the message to the output device before the JVM responded to the last user thread exit.