×

Thread Safety and How to Achieve it in Java

Before diving into the topic, let’s just recap the concept of Multithreading provided by Java where we can create and execute multiple threads of the same object. When these multiple threads share the same object variables, concerns are raised over the safety of each thread due to inconsistent results.

The inconsistent results are obtained while multiple threads are updating the same field value. We need to make sure the Thread Safety by preventing another thread from performing operations while the current thread is working on the same object.

Let’s look at an example to understand more.

Example code:

Java

public class ThreadSafetyExample {


    public static void main(String[] s) throws InterruptedException {
    
        ProcessingThread p = new ProcessingThread();
        Thread one = new Thread(p, "one");
        one.start();
        Thread two = new Thread(p, "two");
        two.start();
        // we need to wait for threads one and twoto finish their   //processing
        one.join();
        two.join();
        System.out.println("Processing count="+p.getCount());
    }


}


class ProcessingThreadExample implements Runnable{
    private int ct;
    
    @Override
    public void run() {
        for(int i=0; i <= 4; i++){
            processSomething(i);
        ct++;
        }
    }


    public int getCount() {
        return this.ct;
    }


    private void processSomething(int i) {
        // processing a defined job 
        try {
            Thread.sleep(i*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
}

Here, we can see in the above program that, the for loop incremented ct value four times by one unit so that its value should become 8 after the completion of execution of threads one and two. Upon executing this program, we end up with the ct value varying between 6, 7, and 8 due to the corruption of the data or inconsistency of the field. This made the Thread unsafe in Java which may end up producing unexpected results.

How to Achieve Thread Safety in Java

Java comes with four ways to make sure the Thread Safety and they are:

  • Synchronization mechanism.
  • By the usage of Volatile Keyword.
  • By the usage of Atomic Variable.
  • By the usage of Final Keyword.

Now let’s see each method to make sure the Thread Safety.

Synchronization Mechanism

Thread Safety can be achieved by the method of synchronization where we use the Java keyword synchronized which creates synchronized code and locks the resource from another thread while the current thread is executing the synchronized code.

We use the keyword synchronized to make a method that is synchronized or we can also create a synchronized block where only some sections of the method need synchronization. While making a method synchronized, first the object gets locked and if the method is static, then the class gets locked.

When there are multiple blocks in a class that is synchronized and an object was locked by one of them, the remaining synchronized blocks cannot be executed by other threads as when an object acquires a lock, all the variables and fields also get locked.

Let’s look at an example program of synchronization to ensure Thread Safety

Java:

class One {
    synchronized void sum(int n)
    {
 
        // Creation of an instance for a thread
        Thread ct = Thread.currentThread();
        for (int i = 1; i <= 5; i++) {
            System.out.println(
                ct.getName() + " : " + (n + i));
        }
    }
}
 
// Class Two extending the thread class
class Two extends Thread {
 
    // Creating an object of class One
    One obj = new One();
    public void run()
    {
 
        // Invoking the method sum() 
        obj.sum(1);
    }
}
class Test {
    public static void main(String[] args)
    {
 
        // Creation of an object for class Two
        Two obj2 = new Two();
 
        // Initialization of the instance t1 of Thread
        // class with the object of class Two
        Thread t1 = new Thread(Two);
 
        // Initialization of the instance t2 of Thread
        // class with the object of class Two
        Thread t2 = new Thread(Two);
 
        // Initialization of thread t1 with name
        //'Thread One'
        t1.setName("Thread One");
 
        // Initialization of thread t2 with name
        //'Thread Two'
        t2.setName("Thread Two");
 
        // Starting the thread instances t1 and t2
        t1.start();
        t2.start();
    }
}

Output:

Thread One : 2
Thread One : 3
Thread One : 4
Thread One : 5
Thread One : 6
Thread Two : 2
Thread Two : 3
Thread Two : 4
Thread Two : 5
Thread Two : 6

Usage of Volatile Keyword

It is another way of achieving Thread Safety, where the object is available to multiple threads at a time without leading to inconsistency. Java provides a keyword, volatile, which is a field modifier, which makes this process happen and ensures the safety of the thread.

Example code:

Java:

public class VolatileExample {
 
    // Initializaton of the volatile variables
    // x y
    static volatile int x = 0, y = 0;
 
    // Defining a static void method
    static void methodone()
    {
        x++;
        y++;
    }
 
    // Defining another static void method
    static void methodtwo()
    {
        System.out.println(
            "x=" + x + " y=" + y);
    }
 
    public static void main(String[] s)
    {
 
        // Creation of an instance one of
        // the Thread class
        Thread one = new Thread() {
            public void run()
            {
                for (int i = 0; i < 5; i++)
                    methodone();
            }
        };
 
        // Creation of an instance two of
        // Thread class
        Thread two = new Thread() {
            public void run()
            {
                for (int i = 1; i <= 5; i++)
                    methodtwo();
            }
        };
 
        // Starting the instances t1 and t2
        one.start();
        two.start();
    }
}

Output:

x=5 y=5
x=5 y=5
x=5 y=5
x=5 y=5
x=5 y=5

Usage of Atomic Variable

We can also achieve Thread Safety by using an atomic variable in our Java program. It makes the multiple threads run concurrently without any interference.

Just look at an example program to understand clearly.

Java:

import java.util.concurrent.atomic.AtomicInteger;
 
class Counter1 {
 
    // Creation of a variable that is
    // of the class type AtomicInteger
    AtomicInteger ct
        = new AtomicInteger();
 
    // Defining the method of increment()
    // to make the value of
    // AtomicInteger variable change
    public void increment()
    {
        ct.incrementAndGet();
    }
}
 
public class TestAtomic {
    public static void main(
        String[] s) throws Exception
    {
 
        // Creation of an instance of
        //  the Counter class
        Counter obj = new Counter1();
 
        // Creation of an instance one of
        // the Thread class
        Thread one = new Thread(
            new Runnable() {
                public void run()
                {
                    for (int i = 1; i <= 4000; i++) {
                        obj.increment();
                    }
                }
            });
 
        // Creation of an instance two
        // of the Thread class
        Thread two = new Thread(
            new Runnable() {
                public void run()
                {
                    for (int i = 1; i <= 4000; i++) {
                        obj.increment();
                    }
                }
            });
 
        // Calling the start() method with one and two thread instances
        one.start();
        two.start();
 
        // Calling the join method with one and two thread instances
        one.join();
        two.join();
 
        System.out.println(obj.ct);
    }
}

Output:

8000

Usage of the Final keyword

We can also make sure of the safety of a thread by using the final variables. By using the Java keyword final, we can assign a permanent reference to a variable, and then once it is assigned, later it cannot reference another object and returns an error if we try to change its value.

Look at an example program.

Java:

// Program to depict the Use of the Final Keyword
 
// The Main class
class Finalclass {
 
    // the driver main method
    public static void main(String s[])
    {
 
        // variable v which is defined using final keyword
        final int v = 50;
        v = 60;
 
        // this program generates error as we tried to change the final     // variable
    }
}

Output:

Compilation Error in java code :- 
prog.java:14: error: cannot assign a value to final variable v
        v = 60;
        ^
1 error

Here, we can observe that, when we tried to change the value of the final variable, the compiler produced an error as the final variable cannot refer to another object once it is assigned with an object initially.


Related Topics

Java Math log1p() Method

The log1p() method of Math class returns the natural logarithmic sum for the specified double argument and 1. Its value is much closer to result of ln(1 + x). Syntax: public static...

2 minutes read.

Java Programming certification

The most common technology utilized in the creation of applications is Java. People and businesses like it because it turns original ideas into useful software solutions. A Java programming certification can...

6 minutes read.

Java Integer longValue() method

The longValue()  method of Java Integer class returns a long value for this Integer after a widening primitive conversion. Syntax public long longValue() Parameters NA Specified by This method is specified by longValue in class Number Return...

1 minute read.

Java Database Connectivity with MySQL

In this tutorial, we will learn how to connect Database with MySQL in Java. 5 Steps to Connect to the Database in Java Load the driver (or) Register the driver classEstablish a...

4 minutes read.

Java Math addExact() Method

The addExact() method of Math class returns the sum of the two arguments, throwing an exception if the result overflows a long or an int. Syntax public static int addExact (int x,...

1 minute read.

How to generate random numbers in Java

Random numbers, also known as fake numbers, are actually a part of a very large sequence, so they are called random numbers. In a defined set of numbers, every number...

6 minutes read.

Java Sort String

In this article, you will be acknowledged about how to sort a string in Java. Introduction Firstly, let us revise what is string Strings are collections of characters that are frequently used in...

4 minutes read.

Java protected vs private

Java : Java is a pure object oriented language. It was introduced by James Gosling in the year 1995. The first public implementation of java was done by sun micro systems...

3 minutes read.

Anagram Program in Java using String

Anagram Program in Java Anagrams are those words that are generated by rearrangement of the letters of another phrase or word. Usually, while doing the rearrangement, the original letters are used...

8 minutes read.

Checked vs Unchecked Exceptions in Java

In this tutorial, we will discuss Java's checked and unchecked Exceptions. Exception An exception is an undesirable event that disrupts the normal flow of the program. An exception is thrown at runtime. It...

4 minutes read.

Matrix Multiplication in Java

In Java, using the binary operator (*) we can perform matrix multiplication. A Matrix is a group of arrays. In the multiplication of matrices, the elements of each row are...

3 minutes read.

Interchange Diagonal elements in Java

In this article, you will be very well acknowledged about what is a matrix with an example. You will also be acknowledged about how to interchange the diagonal elements in...

4 minutes read.

Java Linters

When it comes to programming, everyone makes mistakes. Errors are bad for developers since they are difficult to handle. But handling as many as possible errors will bring out the...

6 minutes read.

Matrix Multiplication Program in Java

Matrix Multiplication Program in Java The matrix multiplication program in Java is the continuation of the matrix program in Java that we have already discussed earlier. In this section, we will...

3 minutes read.

Java String isEmpty() method

Java String isEmpty() method checks whether current String is empty or not. Syntax: public boolean isEmpty() Returns It returns true, if length of String is 0 otherwise false. Java String isEmpty() method example 1    ...

1 minute read.

Java Private keyword

A Java access modifier is a private keyword. It can be used to inner classes, methods, and variables. It is the type of access modifier that is most constrained. Privately declared...

4 minutes read.

Generics vs Wildcard in Java

In generic programming, the question mark (?) is often referred to as the wildcard. It stands for a mysterious type. The wildcard can be used for many different contexts, such as...

4 minutes read.

Java Import Keyword

Java's import keyword used in the code that follows the import statement, a Java class is declared. Once a Java class is declared, it is possible to use the class...

6 minutes read.

Java Code Coverage Tools

Code coverage testing is a crucial metric that gauges how thoroughly the program's source code has been tested. The market is flooded with Code Coverage Tools, making it difficult to...

7 minutes read.

Java List Implementations

ArrayList and LinkedList are the two implementations of List that are for general-purpose. You'll probably utilise an array list the majority of the time because it's quick and provides constant-time...

3 minutes read.