Home » Core Java » Java Thread Example

About Ed de Jongh

Ed de Jongh
Ed has worked in the IT industry for over 20 years, gaining experience in programming, architecture and design. As a seasoned Solution Architect, he is passionate about advancing simplicity and elegance. In addition to solution design, he is also involved in development and integration. Outside of the office, enjoys anything on two wheels and being a dad.

Java Thread Example

1. Introduction

Every Java program has at least one thread, the main thread. This is spun up by the Java Virtual Machine (JVM) when you run your code. Java is multithreaded which means it can utilise multiple threads concurrently. Thankfully, Java makes it easy to work with threads and multithreading. However as developers or programmers we need to take threading into account when designing solutions. In this example we are going to take a look at threads and how they can be implemented.

2. Required Software

The only software we require for this example is Java. I’m using Java 8,
java version “1.8.0_181” .

3. Thread API

While there have been a number of changes to the Thread API through the various Java versions over the years. The fundamentals have stayed the same. This Oracle Threads document shows the various methods available to us: https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html

What is important here is to see the Deprecated methods. This article explains why some of these methods have been deprecated and why they are considered unsafe: https://docs.oracle.com/javase/8/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html

Spend a few minutes going through these docs to help you gain a better understanding of what is available, what is deprecated and why. This will give you a much better understanding of the Java Thread model and concurrency before we dive into the example.

4. Processes

In order to better contextualise Threads we need to understand Processes and how the two are related. The Oracle Java SE tutorial has the following to say about threads and processes:

4.1 Processes and Threads

In concurrent programming, there are two basic units of execution: processes and threads. In the Java programming language, concurrent programming is mostly concerned with threads. However, processes are also important.

A computer system normally has many active processes and threads. This is true even in systems that only have a single execution core, and thus only have one thread actually executing at any given moment. Processing time for a single core is shared among processes and threads through an OS feature called time slicing.

It’s becoming more and more common for computer systems to have multiple processors or processors with multiple execution cores. This greatly enhances a system’s capacity for concurrent execution of processes and threads — but concurrency is possible even on simple systems, without multiple processors or execution cores.

https://docs.oracle.com/javase/tutorial/essential/concurrency/procthread.html

5. Concurrency

The Java tutorial also discusses concurrency. The merriam-webster definition of concurrency (https://www.merriam-webster.com/thesaurus/concurrency) provides the following synonyms: coexistence, coincidence, concurrence.

Given our new found understanding of Threads and Processes from a Java perspective. The concept of Concurrency is much clearer. As of Java 5.0, the java.util.concurrent package was introduced.

Multithreading in java is the process of executing multiple threads simultaneously, concurrently.

Imagine a real world example of a standalone desktop accounting application. There are numerous process running concurrently. File read and write operations. Calculators and UI threads. Logging, caching….the list goes on. Now we really understand the benefits of Multithreading in Java.

6. The thread Lifecycle

A Google image search of java thread life cycle yields a number of varying examples. I think in order to better understand the thread lifecycle we need to look at it from a high level perspective first. Think of it as a very basic overview of threads in

The conceptual Java thread lifecycle is depicted below, but this example is purposefully oversimplified.

Java Thread - Thread Lifecycle
Thread Lifecycle.

In order to better understand the thread lifecycle, we need to look at the Thread class.

6.1 Thread States

The java.lang.Thread class contains an enum for the Thread lifecycle states. A thread can only have one state at any point in its lifecycle.

Java Thread - Thread States.
Thread States.

The above diagram reflects the actual Thread States. The thread class API is available here: https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.State.html

A thread state. A thread can be in one of the following states:

NEW
A thread that has not yet started is in this state.
RUNNABLE
A thread executing in the Java virtual machine is in this state.
BLOCKED
A thread that is blocked waiting for a monitor lock is in this state.
WAITING
A thread that is waiting indefinitely for another thread to perform a particular action is in this state.
TIMED_WAITING
A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.
TERMINATED
A thread that has exited is in this state.

Oracle Java 8 API Docs

These states were first available in Java 1.5. As per the API docs. They represent JVM states and not operating system thread states.

Now that we understand states and the thread lifecycle, we can look at how to instantiate threads in Java.

7. Creating Threads

The examples below are based on the examples from the Java tutorial: https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html

We create threads in Java in on of two ways. We can either implement the Runnable interface:

ThreadRunnableImpl.java
//Here we implement the Runnable interface
public class ThreadRunnableImpl implements Runnable {
	
	//this is the run method which is in the Runnable interface
	//and  we provide an implementation.
    public void run() {
        System.out.println("ThreadRunnableImpl thread is alive!");
    }
    //Here we create a new thread and start it.
    public static void main(String args[]) {
       (new Thread(new ThreadRunnableImpl())).start();

    }

}

Alternately we can subclass java.lang.Thread which implements the Runnable interface:

ExtendThread.java
//This example extends Thread which implements Runnable
public class ExtendThread extends Thread {

    public void run() {
        System.out.println("ExtendThread created this thread!");
    }

    //Notice here we don't call new Thread as we already extend Thread
    public static void main(String args[]) {
        (new ExtendThread()).start();
    }

}

8. Synchronisation

When dealing with more than one thread, there is always a chance of concurrency issues. For example two threads attempting to write to a single file. This could potentially have a disastrous outcome on the file contents. Perhaps even corrupting the file completely. This is known as a Race Condition. Where multiple threads are competing for the same resource.

Another potential pitfall is Memory Consistency Errors. For example one thread could update a variables value and another thread would not be aware of this update. Instead it would use the original value causing inconsistencies. I’m oversimplifying the examples, but you get the idea.

Java provides us with the volatile keyword to address this issue. When we require atomic operations involving multiple threads, we declare variables as volatile. See this document for further info regarding atomic operations and the volatile keyword: https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html

At the method level, Java provides us with the synchronised keyword. A synchronised method only allows access by threads one at a time. Ensuring some defence against thread interference and memory inconsistency errors. Synchronised blocks differ from synchronised methods in that we must specify the object that provides the intrinsic lock. An intrinsic lock means that any other threads must wait until this lock is released by the initial thread before they have access to the object.

Here is the link to the Java Concurrency Tutorial : https://docs.oracle.com/javase/tutorial/essential/concurrency/index.html There is a lot more reading to be done on the topic of Threading in Java. This article and the tutorial are based on Java 8. There have been enhancements and improvements in later releases which have not been covered here.

9. Java Thread – Conclusion

You should have a clearer understanding of threading from a Java perspective. However, this is a very simple introduction and there are a number of topics that we have not covered. In fact when it comes to threading we have barely scratched the surface.

This article should get you off to a good start and there are many more excellent articles and code examples out there. It’s my hope that this article will pique your interest enough to get you to explore Multithreading and Concurrency further. We work with threads every day, but often don’t give a second thought to their implementation and the benefits or pitfalls thereof.

10. Download the Source Code

This was an Example of Java Threading.
Download
You can download the full source code of this example here: Java Thread Example
(No Ratings Yet)
Start the discussion Views Tweet it!

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

 

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

 

and many more ....

 

Receive Java & Developer job alerts in your Area

 

Leave a Reply

avatar
  Subscribe  
Notify of