Sobes.tech
Middle

What is the synchronized block in Java and what problems can arise when using it?

sobes.tech AI

Answer from AI

The synchronized block in Java is used to ensure synchronized access to a shared resource among multiple threads. It guarantees that only one thread can execute the code inside the block at any given time.

Structure of a synchronized block:

synchronized (monitorObject) {
    // Critical section of code
    // Operations with shared resource are performed here
}
  • monitorObject: Any object that acts as a monitor (lock). Threads attempting to enter a synchronized block with the same monitor object will be blocked until the current thread exits the block.

Problems that can arise when using synchronized:

  • Deadlock: Two or more threads wait for a resource held by another thread, leading to a program hang. This can happen if threads try to acquire locks in different orders.
  • Performance degradation: Synchronization blocks block other threads waiting for the monitor, which can slow down parallel applications.
  • Inapplicability to certain scenarios: synchronized provides exclusive access. In some cases, more flexible access control might be needed (e.g., multiple threads reading simultaneously, writing in one thread).
  • Debugging complexity: Synchronization issues can be non-obvious and difficult to reproduce and debug.

Example of deadlock:

class Resource {
    private Object lock1 = new Object();
    private Object lock2 = new Object();

    public void method1(Resource other) {
        synchronized (lock1) {
            try {
                Thread.sleep(100); // Simulate work
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " acquired lock1");
            synchronized (other.lock2) {
                System.out.println(Thread.currentThread().getName() + " acquired other's lock2");
            }
        }
    }

    public void method2(Resource other) {
        synchronized (lock2) {
             try {
                Thread.sleep(100); // Simulate work
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " acquired lock2");
            synchronized (other.lock1) {
                System.out.println(Thread.currentThread().getName() + " acquired other's lock1");
            }
        }
    }
}

public class DeadlockExample {
    public static void main(String[] args) {
        Resource r1 = new Resource();
        Resource r2 = new Resource();

        new Thread(() -> r1.method1(r2), "Thread-1").start();
        new Thread(() -> r2.method2(r1), "Thread-2").start();
    }
}

In this example, Thread-1 tries to acquire lock1 on r1 and then lock2 on r2. Thread-2 tries to acquire lock2 on r2 and then lock1 on r1. If they acquire the first locks simultaneously, a deadlock occurs.

What is the synchronized block in Java and what… - sobes.tech