Saturday 11 March 2023

Thread Synchronization or Thread safety in Java

When more than one thread has to use a shared resource, Java finds way of ensuring that only one thread uses the resources at one point of time; this is called synchronization.

In Java, thread synchronization refers to the mechanisms used to ensure that multiple threads access shared resources in a safe and predictable manner. It is important to synchronize threads when multiple threads access the same shared resources, such as variables or objects, to avoid race conditions, where the outcome of the program depends on the relative timing of events between the threads.

Thread safety is the property of a program that guarantees that it behaves correctly when executed concurrently by multiple threads. A thread-safe program is one that guarantees thread safety by using synchronization to ensure that shared resources are accessed in a predictable and safe manner.

In java, each object is associated with a lock. The term lock refers to the access granted to a particular thread that has entered a synchronized method.

Monitor refers to a portion of the code in the program. It contain one specific region that can be occupied by only one thread at a time. This specific region within a monitor is known as critical section.

A thread has exclusive lock from the time it enters the critical section to the time it leaves. That is, the data (or resources) is exclusively served for the thread, and any other thread has to wait to access that data.

The key concept in synchronization is the monitor.

When there are several synchronized methods attempting to act on an object, only one synchronized method may be active on an object at one instance of time and all other threads attempting to invoke synchronized methods must be wait.

There are two main mechanisms for thread synchronization in Java: synchronized methods and synchronized blocks. Synchronized methods ensure that only one thread can execute the method at a time, while synchronized blocks allow more fine-grained control over which parts of the code are synchronized.

To make a method thread-safe in Java, you can add the synchronized keyword to the method declaration. This ensures that only one thread can execute the method at a time, preventing race conditions.

Here is an example of a thread-safe Java class using synchronized methods:

class Counter {
   private int count = 0;

   public synchronized void increment() {
      count++;
   }

   public synchronized void decrement() {
      count--;
   }

   public synchronized int getCount() {
      return count;
   }
}

class CounterThread extends Thread {
   private Counter counter;

   public CounterThread(Counter counter) {
      this.counter = counter;
   }

   public void run() {
      for (int i = 0; i < 10000; i++) {
         counter.increment();
      }
   }
}

public class SynchronizationExample {
   public static void main(String[] args) throws InterruptedException {
      Counter counter = new Counter();
      CounterThread thread1 = new CounterThread(counter);
      CounterThread thread2 = new CounterThread(counter);

      thread1.start();
      thread2.start();
      thread1.join();
      thread2.join();

      System.out.println("Count: " + counter.getCount());
   }
}


In this program, we have a Counter class that has three synchronized methods: increment, decrement, and getCount. These methods are synchronized to prevent race conditions and ensure that only one thread can access them at a time.

We also have a CounterThread class that extends the Thread class and has a reference to a Counter object. The run method of this class simply calls the increment method of the Counter object 10,000 times.

In the main method of the SynchronizationExample class, we create two CounterThread objects and start them. We then wait for them to finish using the join method. Finally, we print the value of the count using the getCount method of the Counter object.

When we run this program, we should see that the count is always 20,000, indicating that the synchronization is working correctly and preventing race conditions.

In Java, synchronized blocks are another way to achieve thread safety and prevent race conditions. A synchronized block is a block of code that is synchronized on a specific object.

Here is an example program that demonstrates the use of synchronized blocks in Java:

class Counter {
   private int count = 0;

   public void increment() {
      synchronized (this) {
         count++;
      }
   }

   public void decrement() {
      synchronized (this) {
         count--;
      }
   }

   public int getCount() {
      synchronized (this) {
         return count;
      }
   }
}

class CounterThread extends Thread {
   private Counter counter;

   public CounterThread(Counter counter) {
      this.counter = counter;
   }

   public void run() {
      for (int i = 0; i < 10000; i++) {
         counter.increment();
      }
   }
}

public class SynchronizedBlockExample {
   public static void main(String[] args) throws InterruptedException {
      Counter counter = new Counter();
      CounterThread thread1 = new CounterThread(counter);
      CounterThread thread2 = new CounterThread(counter);

      thread1.start();
      thread2.start();
      thread1.join();
      thread2.join();

      System.out.println("Count: " + counter.getCount());
   }
}


In this program, we have a Counter class that has three methods: increment, decrement, and getCount. Each of these methods is synchronized on the this object using a synchronized block. This ensures that only one thread can access the block of code inside the block at a time.

We also have a CounterThread class that extends the Thread class and has a reference to a Counter object. The run method of this class simply calls the increment method of the Counter object 10,000 times.

In the main method of the SynchronizedBlockExample class, we create two CounterThread objects and start them. We then wait for them to finish using the join method. Finally, we print the value of the count using the getCount method of the Counter object.

When we run this program, we should see that the count is always 20,000, indicating that the synchronization is working correctly and preventing race conditions.

In summary, thread synchronization and thread safety are important concepts in Java that ensure that multiple threads can access shared resources in a safe and predictable manner. Synchronized methods and synchronized blocks are two mechanisms used to achieve thread synchronization and thread safety in Java.

0 comments :

Post a Comment

Note: only a member of this blog may post a comment.

Machine Learning

More

Advertisement

Java Tutorial

More

UGC NET CS TUTORIAL

MFCS
COA
PL-CG
DBMS
OPERATING SYSTEM
SOFTWARE ENG
DSA
TOC-CD
ARTIFICIAL INT

C Programming

More

Python Tutorial

More

Data Structures

More

computer Organization

More
Top