Multithreading in Java — Part 1

Venkat
5 min readMar 18, 2023

--

Introduction

Humans are by nature lazy. They dont want to wait for the completion of one task to start over with another. And this is the sole reason why you see others (and yourself) perform multiple tasks at a time like listening to music in background and coding (the most anticipated duo).

This is the same thing that we see the CPU do. But ever thought how does it execute numerous tasks at a time? Let’s learn in this article.

Threading

Threading is a technique which is used to make efficient use of system resources by enabling the power to execute multiple threads of a single process independently. A thread represents a separate path of execution. This thread that we talk about is the smallest unit of executable code. It has its applications in several domains like web servers, database systems, and GUIs. By the use of threads, applications can process multiple incoming requests and respond to them simultaneously.

User Level Threading

User Level Threading is a process of creating and managing threads at the surface level by the user, without any involvement of operating system. The standard threading library provided by Java is the best example of user level threading.

Kernel Level Threading

Kernel Level Threading is a technique in which operating system kernel manages the allocation of threads and their priority. To some extent, kernel threading represents real parallelism and comes handy for heavy applications but it comes with its disadvantages too which includes problems in thread synchronization and context switching. Hence it poses threat to the performance of those applications.

Kernel level threading in Java was introduced in Java 1.5 with java.util.concurrent. This package provides an efficient and thread safe framework for parallel programming that can take advantage of multiple cores and processors. It includes predefined classes of Locks, Barrier and Semaphores.

Java Thread Model

Java Thread Model is not that of a Event loop with polling. Unlike JavaScript, Java has a separate thread management system of its own which can, on requirement, pause and resume threads, send them to a sleep state or in short, can block threads to resume other threads. Java Multithreading API makes use of sleep(), wait(), notify(), notifyAll(), join(), etc. to relinquish control over the thread.

Java makes use of the main thread to run any application or program. This is the sole reason to why you would have seen Runtime Exceptions showing up linkages to main thread in its stack trace.

Exception in thread “main” …

Java maintains a different stack for each thread inside of JVM. Hence for the main() method, it uses the “main” thread. This thread has the highest priority of all threads existing as it is the one responsible to execute an application. It is a thread from which other threads are created and managed and it is the last thread to finish its execution as there are various shutdown operations before the program gets terminated.

Java and Multithreading

Java has always updated its standards for multithreading and concurrency as the years went by. Let’s run our eyes through how it has been through Java’s Multithreading culture.

  • Java 1.5 : Java introduces java.util.concurrent which provides a thread safe, efficient and high level framework for implementing parallel programming into Java programs. Classes introduced in this package like Executor, ThreadPoolExecutor and ForkJoinPool streamline the programs by making use of multiple processors.
  • Java 8 : Java introduces the Future API that enables asynchronous programming and its results to be dealth with without the overhead to manage low level threads. It also modified and introduced a new set of concurrent classes which are thread safe (multiple threads can act on it simultaneously) like ConcurrentHashMap, ConcurrentLinkedQueue, etc. It also introduced classes like CopyOnWriteArrayList which basically uses the copy-and-write process to make ArrayList thread safe without the need of explicit synchronization.
  • Java 9: Flow API was introduced. It is a library for reactive programming which deals with reactive streams ( data streams which let out data asynchronously). It is responsible for interacting with reactive streams.
  • Java 10 : Concurrent API of Java was improved for making the creation and management of ThreadPool, a new class named VarHandle which deals with the management of atomic variables to perform low level operations too.
  • Java 11 : HttpClient, an asynchronous data request and response API, was introduced.
  • Java 13 : Enhanced VarHandle class for safe sharing of data between threads without synchronization.
  • Java 14 : Enhancements to CompletableFuture, timeout methods were added.
  • Java 17 : Added to Executors method to the Concurrent API.

User Level Threading and Multithreading in Java

Java Multithreading API lets the user divide the task into several lightweight green threads using either extending the Thread class or implementing the Runnable interface.

Thread class.

By extending the Thread class, one can create a green thread in Java. This is how you would create a green thread.

Using Thread class.

public class ThreadCreationExample extends Thread{

@Override
public void run(){
System.out.println("This is a message originating from run() method.");
}
}

Using Runnable interface

public class ThreadCreationViaRunnable implements Runnable{
@Override
public void run() {
System.out.println("Message via Runnable");
}
}

Methods of Thread class.

Venkat

When dealing with threads and its methods, one needs to keep in mind of InterruptedException being generated at runtime during suspending and resuming of threads. This is likely to be thrown when another thread tries to interrupt an alive thread (maybe suspended by sleep method).

But how to decide which approach to choose to create a green thread in Java. Its simple to answer. A Java class cannot extend more than one class but multiple inheritance in the form of interfaces is allowed. Hence its always preferred to use Runnable than to use Thread class.

Thread State and Priorities

A thread state might be broken into different phases as explained in the following figure.

Thread Life Cycle

Thread Priorities are integers which are assigned to threads so as to make it easier to decide for the thread scheduler of JVM which thread to execute first. The normal priority of a thread is 5. When two tasks are assigned to two threads with same priorities, the order of execution of thread is randomized.

This brings us to the end of this first part of multithreading in Java. We will study about synchronization and deadlocks in the upcoming post. Till then, stay tuned. Thanks !!

--

--

Venkat
Venkat

Written by Venkat

A High School student making Java simple to comprehend and understand with Project Java.

No responses yet