Threads and Multithreading – Part 3

Threads - images of multicoloured threads

This is the third post in this series. If you missed the previous posts, you can find them here:

It’s important to be aware of the various states that a thread can be in when we control threads manually.

In this post, we’ll look at daemon threads and thread groups.

Daemon Threads

The term “demon” is commonly thought of as an evil spirit, but the original term “daemon” meant a spiritual being that influenced a person’s character. Daemon is an older form of the word demon. The ancient Greeks considered a daemon (an alternative spelling is “daimon”) to be a guardian angel or guardian spirit.

In modern usage, the word daemon is pronounced as DEE-mon (the same pronunciation as demon). However, when we are talking about computer software, we tend to pronounce daemon as DAY-mon.

In Java, a daemon thread is a low-priority thread that runs in the background to perform background processing of service-related tasks such as garbage collection.

Daemon threads provide services to user threads. Their only role is to serve user threads. A daemon thread’s life depends on the user threads, i.e. when all the user threads die, the JVM terminates all daemon threads automatically.

Daemon Thread Methods

The public final void setDaemon(boolean state) method can be called to change a normal user thread into a daemon thread. This method must be called before the thread is started.

Daemon threads are processed in the background, and the main program does not need to wait for them to die before it can exit. JVM terminates itself when all the user threads are finished executing. The JVM can exit when the only remaining running threads are daemon threads. Daemon threads can not prevent the JVM from exiting after all the user threads die. In this context, a daemon thread can be thought as an extremely low priority thread.

We can check if a thread is a daemon thread by calling the public final boolean isDaemon() method.

Example Code

The following is a simple example of running two threads. One thread is implemented as an anonymous inner class; the other as a lambda expression. Both could have been implemented in either way. The difference is more for purposes of revision and code comparison than for any specific functional requirement.

The first task prints its default name and then enters an infinite loop printing dots. The second task just prints its name and exits. We run the second task twice: once sequentially in the main thread (just for interest) and once in parallel, i.e. as a proper thread.

We set the first task to be a daemon thread with the statement task1.setDaemon(true); If we do that, the JVM terminates normally after the two user threads (main and task2) have completed. The first task is a daemon thread, and as such, the infinite loop doesn’t prevent the JVM from closing down.

However, if we run the first task as a normal user thread by either commenting out the setDaemon(true) call, or changing it to task1.setDaemon(false);, then the JVM does not shut down. The user thread running the infinite loop continues to run even after the main user thread has completed. We have to press Ctrl-C in the console of a Windows machine to break out of the running program.

In most command line interfaces, Ctrl-C is understood as an operating system signal instead of a text copy. It is used to stop the currently running task and return control to the command prompt.

public class DaemonThreadTest {

    public static void main(String args[]) {

        Thread task1 = new Thread (
            // anonymous inner class
            new Runnable() {
                @Override
                public void run() {
                    String threadName = Thread.currentThread().getName();
                    System.out.println("Hello " + threadName);
                    while (true) {
                        System.out.print('.');
                    }
                }
            }
        );

        Runnable task2 = () -> {
                String threadName = Thread.currentThread().getName();
                System.out.println("Hello " + threadName);
                };

        // task1 runs in parallel as separate thread
        task1.setDaemon(true);
        task1.start();

        // task2 runs sequentially in main thread
        task2.run();

        // task2 runs in parallel as separate thread
        Thread thread = new Thread(task2);
        thread.start();

        System.out.println("Done!");

    } // end of main

} // end of class

With task1 being a daemon thread, we’ll notice that the application has non-deterministic behaviour. Every time we run it, we’ll get a different output. This can easily be seen by the time of dots being printed, as well as the order in which the thread names and the Done! message are printed.

Thread Groups

Instead of controlling each thread individually, a thread group can be used to control a number of threads with the thread control methods. We can construct a thread group with the following code:

ThreadGroup g = new ThreadGroup("ThreadGroupName");
Thread t = new Thread(g, "ThreadName");

Almost anything we can do with an individual thread, we can do with thread groups. We can start, stop, resume, suspend, and interrupt the thread group. We can set all threads in the group to be daemon threads, and set the maximum priority of all the threads. We can count, list and enumerate all the threads.

Conclusion

More and more of the iceberg of threads is being exposed. Lots more to come!

In the next post we’ll look at how to interrupt threads and handle them being interrupted. We’ll also investigate the use of the synchronized keyword, and the wait() and notify() methods of the Object class.

Please share your comments.

Until then, stay safe and keep coding!

Leave a Comment

Your email address will not be published. Required fields are marked *

Code like a Java Guru!

Thank You

We're Excited!

Thank you for completing the form. We're excited that you have chosen to contact us about training. We will process the information as soon as we can, and we will do our best to contact you within 1 working day. (Please note that our offices are closed over weekends and public holidays.)

Don't Worry

Our privacy policy ensures your data is safe: Incus Data does not sell or otherwise distribute email addresses. We will not divulge your personal information to anyone unless specifically authorised by you.

If you need any further information, please contact us on tel: (27) 12-666-2020 or email info@incusdata.com

How can we help you?

Let us contact you about your training requirements. Just fill in a few details, and we’ll get right back to you.

Your Java tip is on its way!

Check that incusdata.com is an approved sender, so that your Java tips don’t land up in the spam folder.

Our privacy policy means your data is safe. You can unsubscribe from these tips at any time.