How Do Threads Work?

There are two primary ways to create a thread:

  1. Subclass Thread by extending the Thread class and overriding it’s run() method

  2. Implement a Runnable class implementation as an anonymous class or Lambda expression to a Thread constructor. This is preferred since you can build the task logic and separate it from the actual execution (Thread).

Starting a Thread uses the .start() method. Calling run() from the implementation only executes the code in the thread, not run the actual thread.

Thread.sleep(ms) is used to pause execution for a certain duration.

Instead of using stop(), we want to use a boolean flag that the thread checks periodically to see if an exit from the loop is warranted.

Something to note is the use of the synchronized keyword. This puts a lock on the thread that calls the method its on, so that whenever a thread accesses or leaves, it will have to refresh or flush it’s variable memory respectively. In the case of stopping a thread, it makes sure that all threads always have updated information on whether a thread is called to stop or not (since the fields are cached).

A more efficient way with less overhead, however, is the use of the volatile keyword when declaring the flag. This bypasses the need to even use a lock, making sure that the variable is never cached and must be refreshed on every access.


Runnable runnable = () -> {
    System.out.println("Lambda Thread is running");
};

Thread thread = new Thread(runnable);
thread.start()

Above is an example of utilizing Lambda to create a Java thread.


While the main thread is a User Thread, setting a thread as daemon using thread.setDaemon(true) will allow that thread to run in the background while allowing the JVM to close when an application is closed. This shouldn’t be used on anything that writes to files, databases or networks.