Several methods of thread safety in Java

Posted by elite_prodigy on Fri, 11 Feb 2022 18:19:41 +0100

We know Java One feature, multithreading, is a process that runs multiple threads at the same time. When multiple threads process the same data and our data value changes, this situation is not thread safe, and we will get inconsistent results. When a thread already works on an object and prevents another thread from working on the same object, this process is called thread safety.

In Java, thread safety is realized by the following methods:

  1. Using thread synchronization
  2. Using the Volatile keyword
  3. Using Atomic variables
  4. Use the final keyword

Using thread synchronization

Synchronization is a process that allows only one thread to complete a specific task at a time. This means that when multiple threads execute at the same time and want to access the same resource at the same time, inconsistency will occur. Therefore, synchronization is used to resolve inconsistencies by allowing only one thread at a time.

Synchronization uses the synchronized keyword. Synchronized is a modifier that acts as a synchronization area.

class A {
  synchronized void sum(int n)
  {

    // Creating a thread instance
    Thread t = Thread.currentThread();
    for (int i = 1; i <= 5; i++) {
      System.out.println(
        t.getName() + " : " + (n + i));
    }
  }
}

// Class B extending thread class
class B extends Thread {

  // Creating an object of class A
  A a = new A();
  public void run()
  {

    // Calling sum() method
    a.sum(10);
  }
}
class Test {
  public static void main(String[] args)
  {

    // Creating an object of class B
    B b = new B();

    // Initializing instance t1 of Thread
    // class with object of class B
    Thread t1 = new Thread(b);

    // Initializing instance t2 of Thread
    // class with object of class B
    Thread t2 = new Thread(b);

    // Initializing thread t1 with name
    //'Thread A'
    t1.setName("Thread A");

    // Initializing thread t2 with name
    //'Thread B'
    t2.setName("Thread B");

    // Starting thread instance t1 and t2
    t1.start();
    t2.start();
  }
}

output

Thread A : 11
Thread A : 12
Thread A : 13
Thread A : 14
Thread A : 15
Thread B : 11
Thread B : 12
Thread B : 13
Thread B : 14
Thread B : 15

Using the Volatile keyword

Volatile keyword is a field modifier that ensures that an object can be used by multiple threads simultaneously without any problems. Volatile is a good way to ensure that Java programs are thread safe. The volatile keyword can be used as an alternative to thread safety in Java.

public class VolatileExample {

  // Initializing volatile variables
  // a, b
  static volatile int a = 0, b = 0;

  // Defining a static void method
  static void method_one()
  {
    a++;
    b++;
  }

  // Defining static void method
  static void method_two()
  {
    System.out.println(
      "a=" + a + " b=" + b);
  }

  public static void main(String[] args)
  {

    // Creating an instance t1 of
    // Thread class
    Thread t1 = new Thread() {
      public void run()
      {
        for (int i = 0; i < 5; i++)
          method_one();
      }
    };

    // Creating an instance t2 of
    // Thread class
    Thread t2 = new Thread() {
      public void run()
      {
        for (int i = 0; i < 5; i++)
          method_two();
      }
    };

    // Starting instance t1 and t2
    t1.start();
    t2.start();
  }
}

output

a=5 b=5
a=5 b=5
a=5 b=5
a=5 b=5
a=5 b=5

Using Atomic variables

Using atomic variables is another way to achieve thread safety in java. When multiple threads share variables, atomic variables ensure that threads do not crash each other.

import java.util.concurrent.atomic.AtomicInteger;

class Counter {

  // Creating a variable of
  // class type AtomicInteger
  AtomicInteger count
    = new AtomicInteger();

  // Defining increment() method
  // to change value of
  // AtomicInteger variable
  public void increment()
  {
    count.incrementAndGet();
  }
}

public class TestCounter {
  public static void main(
    String[] args) throws Exception
  {

    // Creating an instance of
    // Counter class
    Counter c = new Counter();

    // Creating an instance t1 of
    // Thread class
    Thread t1 = new Thread(
      new Runnable() {
        public void run()
        {
          for (int i = 1; i <= 2000; i++) {
            c.increment();
          }
        }
      });

    // Creating an instance t2
    // of Thread class
    Thread t2 = new Thread(
      new Runnable() {
        public void run()
        {
          for (int i = 1; i <= 2000; i++) {
            c.increment();
          }
        }
      });

    // Calling start() method with t1 and t2
    t1.start();
    t2.start();

    // Calling join method with t1 and t2
    t1.join();
    t2.join();

    System.out.println(c.count);
  }
}

output

4000

Use the final keyword

The final variable is also thread safe in java, because once a reference of one object is allocated, it cannot point to a reference of another object.

public class FinalTest {

  // Initializing a string
  // variable of final type
  final String str
    = new String("hello");

  // Defining a method to
  // change the value of the final
  // variable which is not possible,
  // hence the error will be shown
  void method()
  {
    str = "world";
  }
}

output

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

This article is an original article from big data to artificial intelligence blogger "xiaozhch5", which follows the CC 4.0 BY-SA copyright agreement. Please attach the original source link and this statement for reprint.

Original link: https://lrting.top/backend/3755/