Thread Interference

Thread interference in Java refers to the situation where two or more threads access shared data or resources concurrently without proper synchronization, leading to unexpected and erroneous behavior. This issue arises due to the non-atomicity of operations involving shared resources, where an interleaving of operations from multiple threads can result in inconsistent or incorrect state.

To avoid thread interference and ensure correct behavior when multiple threads access shared resources concurrently, you can use synchronization mechanisms such as synchronized methods, synchronized blocks, ReentrantLock, or atomic variables (AtomicInteger, AtomicLong, etc.). These mechanisms ensure that only one thread can access the shared resource at a time, preventing interleaved operations that lead to inconsistencies.

Consider a simple counter class that is not thread-safe:

//ThreadInterferenceDemo.java
class Counter {
    private int count = 0;
    public void increment() {
        // Non-atomic operation
        int temp = count;
        temp = temp + 1;
        count = temp;
    }

    public int getCount() {
        return count;
    }
}
public class ThreadInterferenceDemo {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        // Thread 1 increments the counter 1000 times
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        // Thread 2 increments the counter 1000 times
        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        // Start both threads
        thread1.start();
        thread2.start();
        // Wait for both threads to finish
        thread1.join();
        thread2.join();
        // Expected count after both threads finish (should be 2000)
        System.out.println("Final Count: " + counter.getCount()); // May not be 2000 due to thread interference
    }
}

/*
C:\>javac ThreadInterferenceDemo.java

C:\>java ThreadInterferenceDemo
Final Count: 2000

C:\>java ThreadInterferenceDemo
Final Count: 1974

C:\>java ThreadInterferenceDemo
Final Count: 2000

C:\>java ThreadInterferenceDemo
Final Count: 1889

C:\>java ThreadInterferenceDemo
Final Count: 2000

*/

Here’s an example of using synchronized methods to make the Counter class thread-safe:

//SynchronizedThreadInterferenceDemo.java
class Counter {
    private int count = 0;
    public synchronized void increment() {
        // Non-atomic operation
        int temp = count;
        temp = temp + 1;
        count = temp;
    }

    public synchronized int getCount() {
        return count;
    }
}
public class SynchronizedThreadInterferenceDemo {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        // Thread 1 increments the counter 1000 times
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        // Thread 2 increments the counter 1000 times
        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        // Start both threads
        thread1.start();
        thread2.start();
        // Wait for both threads to finish
        thread1.join();
        thread2.join();
        // Expected count after both threads finish (should be 2000)
        System.out.println("Final Count: " + counter.getCount()); // May not be 2000 due to thread interference
    }
}

/*


C:\>java SynchronizedThreadInterferenceDemo
Final Count: 2000

C:\>java SynchronizedThreadInterferenceDemo
Final Count: 2000

C:\>java SynchronizedThreadInterferenceDemo
Final Count: 2000

*/

Thread interference is a critical issue in concurrent programming where shared resources are accessed by multiple threads without proper synchronization. Understanding and addressing thread interference is essential to ensure correct and reliable behavior in multi-threaded applications.

Scroll to Top