Threads in Java

Vishwesh Kulkarni
8 min readMay 31, 2021

What is Thread In java

A thread, in the context of Java, is the path followed when executing a program. All Java programs have at least one thread, known as the main thread, which is created by the Java Virtual Machine (JVM) at the program’s start, when the main() method is invoked with the main thread.

In Java, creating a thread is accomplished by implementing an interface and extending a class. Every Java thread is created and controlled by the java.lang.Thread class.

A single-threaded application has only one thread and can handle only one task at a time

There are two types of threads in an application user thread and daemon thread. When we start an application, main is the first user thread created and we can create multiple user threads as well as daemon threads. When all the user threads are executed, JVM terminates the program.

We can create Threads by either implementing Runnable interface or by extending Thread Class.

Thread t = new Thread(new Runnable(){

@Override

public void run() {

}

});

Above is a one liner statement to create new Thread, Here we are creating Runnable as Anonymous Class

How Thread Is Different From Process

A process is an active program i.e. a program that is under execution. It is more than the program code as it includes the program counter, process stack, registers, program code etc. Compared to this, the program code is only the text section.

A thread is a lightweight process that can be managed independently by a scheduler. It improves the application performance using parallelism. A thread shares information like data segment, code segment, files etc. with its peer threads while it contains its own registers, stack, counter etc.

Processes require more time for context switching as they are more heavy. Threads require less time for context switching as they are lighter than processes. Processes are totally independent and don’t share memory. A thread may share some memory with its peer threads. All the different processes are treated separately by the operating system. All user level peer threads are treated as a single task by the operating system. If a process gets blocked, remaining processes can continue execution. If a process gets blocked, remaining processes can continue execution. If a user level thread gets blocked, all of its peer threads also get blocked. Processes require more resources than threads.

Life-Cycle of a Thread

Below diagram shows different states of thread life cycle in java. We can create a thread in java and start it but how the thread states change from Runnable to Running to Blocked depends on the OS implementation of thread scheduler and java doesn’t have full control on that.

A thread lies only in one of the shown states at any instant:

1. New

2. Runnable

3. Blocked / Waiting

4. Timed Waiting

5. Terminated

  • New − A new thread begins its life cycle in the new state. It remains in this state until the program starts the thread. It is also referred to as a born thread.
  • Runnable − After a newly born thread is started, the thread becomes runnable. A thread in this state is considered to be executing its task.
  • Blocked/Waiting − Sometimes, a thread transitions to the waiting state while the thread waits for another thread to perform a task. Thread transitions back to the runnable state only when another thread signals the waiting thread to continue executing.
  • Timed Waiting − A runnable thread can enter the timed waiting state for a specified interval of time. A thread in this state transitions back to the runnable state when that time interval expires or when the event it is waiting for occurs.
  • Terminated (Dead) − A runnable thread enters the terminated state when it completes its task or otherwise terminates.

Monitoring The Threads

Java applications in production can have hundreds or thousands of threads running in parallel. When an issue is detected — e.g., the JVM is taking up very high CPU resources — an obvious question is which thread is causing the CPU spike? And an immediate next question is which code snippet is the thread executing? While it is important to report this information in real-time, it is also important that these details are made available for historical analysis. . For instance, your application could have had a CPU spike at 2 am and become unresponsive, forcing your operations team to restart the server. Having the details of what threads in the JVM were running at 2 am and which thread was taking up CPU is a key to being able to diagnose the application performance issue.

At the same time, it is also important to track the number of threads being spawned in the JVM. If too many threads are created in parallel, the JVM memory must be sufficiently sized to handle this load. If not, application performance will suffer. Administrators also must track cases of thread leaks — i.e., instances when the number of threads in the JVM keep on increasing and ultimately cause the JVM to crash.

What is Multi-Threading?

Multithreading in Java is a process of executing two or more threads simultaneously to maximum utilization of CPU. Multithreaded applications execute two or more threads run concurrently. Hence, it is also known as Concurrency in Java. Each thread runs parallel to each other. Mulitple threads don’t allocate separate memory area, hence they save memory. Also, context switching between threads takes less time.

Prioritizing Threads in Java

We can set different priorities to different Threads but it doesn’t guarantee that higher priority thread will execute first than lower priority thread. Thread scheduler is the part of Operating System implementation and when a Thread is started, it’s execution is controlled by Thread Scheduler and JVM doesn’t have any control on it’s execution.

Priority of a thread describes how early it gets execution and selected by the thread scheduler. In Java, when we create a thread, always a priority is assigned to it. In a Multithreading environment, the processor assigns a priority to a thread scheduler. The priority is given by the JVM or by the programmer itself explicitly. The range of the priority is between 1 to 10 and there are three constant variables which are static and used to fetch priority of a Thread.

1. Public Static unt MIN_PRIORITY : It holds the minimum priority that can be given to a thread. The value for this is 1.

2. Public Static int NORM_PRIORITY : It is the default priority that is given to a thread if it is not defined. The value for this is 0.

3. Public Static int MAX _PRIORITY : It is the maximum priority that can be given to a thread. The value for this is 10.

Get and Set methods in Thread priority

1. In Java, getPriority() method is in java.lang.Thread package. it is used to get the priority of a thread.

2. In Java setPriority(intnewPriority) method is in java.lang.Thread package. It is used to set the priority of a thread. The setPriority() method throws IllegalArgumentException if the value of new priority is above minimum and maximum limit.

Thread Safety and Synchronisation

Thread safety in java is the process to make our program safe to use in multithreaded environment, there are different ways through which we can make our program thread safe.

· Synchronization is the easiest and most widely used tool for thread safety in java.

· Use of Atomic Wrapper classes from java.util.concurrent.atomic package. For example AtomicInteger

· Use of locks from java.util.concurrent.locks package.

· Using thread safe collection classes, check this post for usage of ConcurrentHashMap for thread safety.

· Using volatile keyword with variables to make every thread read the data from memory, not read from thread cache.

Synchronization is the tool using which we can achieve thread-safety, JVM guarantees that synchronized code will be executed by only one thread at a time. java keyword synchronized is used to create synchronized code and internally it uses locks on Object or Class to make sure only one thread is executing the synchronized code.

· Java synchronization works on locking and unlocking of the resource before any thread enters into synchronized code, it has to acquire the lock on the Object and when code execution ends, it unlocks the resource that can be locked by other threads. In the meantime, other threads are in wait state to lock the synchronized resource.

· Synchronized(this) will lock the Object before entering into the synchronized block

Inter-Thread Communication

Inter-thread communication in Java is a technique through which multiple threads communicate with each other.

It provides an efficient way through which more than one thread communicate with each other by reducing CPU idle time. CPU idle time is a process in which CPU cycles are not wasted.

When more than one threads are executing simultaneously, sometimes they need to communicate to each other by exchanging information with each other. A thread exchanges information before or after it changes its state.

Thread B waits for Thread A to produce data, it will waste many CPU cycles. But if threads A and B communicate with each other when they have completed their tasks, they do not have to wait and check each other’s status every time.

Inter thread communication in Java can be achieved by using three methods provided by Object class of java.lang package.

1. wait() Method in Java

wait() method in Java notifies the current thread to give up the monitor (lock) and to go into sleep state until another thread wakes it up by calling notify() method. This method throws InterruptedException. Following are syntaxes of different types of wait method.

Syntax:

public final void wait()
public final void wait(long millisecond) throws InterruptedException
public final void wait(long millisecond, long nanosecond) throws Interrupted Exception

2. notify() method in Java

The notify() method wakes up a single thread that called wait() method on the same object. If more than one thread is waiting, this method will awake one of them.

Syntax:

public final void notify()

3. notifyAll() method in Java

The notifyAll() method is used to wake up all threads that called wait() method on the same object. The thread having the highest priority will run first.

Syntax:

public final void notifyAll()

Advantages and Applications of Threads

· It doesn’t block the user because threads are independent and you can perform multiple operations at the same time.

· You can perform many operations together, so it saves time.

· Threads are independent, so it doesn’t affect other threads if an exception occurs in a single thread.

· Enhanced performance by decreased development time

· Simplified and streamlined program coding

· Improvised GUI responsiveness

· Simultaneous and parallelized occurrence of tasks

· Better use of cache storage by utilization of resources

· Decreased cost of maintenance

· Better use of CPU resource

Authors

SYIC-B

1. Soumitra Kulkarni (RN — 22)

2. Suyash Kulkarni (RN — 23)

3. Vishwesh Kulkarni (RN — 24)

4. Abhishek Kumbhar (RN — 25)

(STUDENTS — VISHWAKARMA INSTITUTE OF TECHNOLOGY)

--

--