Sobes.tech
Middle

What synchronization methods do you know in Java?

sobes.tech AI

Answer from AI

In Java, there are several main synchronization mechanisms for managing access to shared resources from different threads:

  • synchronized keyword: Can be applied to methods and code blocks. Ensures atomicity and visibility.

    // Synchronizing a method
    public synchronized void increment() {
        count++;
    }
    
    // Synchronizing a code block
    public void updateList() {
        synchronized (myList) {
            myList.add(newItem);
        }
    }
    
  • Explicit locks (java.util.concurrent.locks)

    • ReentrantLock: Reentrant, allows multiple lock acquisitions by the same thread.

      import java.util.concurrent.locks.ReentrantLock;
      
      private final ReentrantLock lock = new ReentrantLock();
      
      public void performTask() {
          lock.lock();
          try {
              // Critical section
          } finally {
              lock.unlock();
          }
      }
      
    • ReentrantReadWriteLock: Separates lock into read and write, allowing multiple threads to read simultaneously but only one to write.

      import java.util.concurrent.locks.ReentrantReadWriteLock;
      
      private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
      private final ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
      private final ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();
      
      public void readData() {
          readLock.lock();
          try {
              // Reading data
          } finally {
              readLock.unlock();
          }
      }
      
      public void writeData() {
          writeLock.lock();
          try {
              // Writing data
          } finally {
              writeLock.unlock();
          }
      }
      
  • Semaphores (Semaphore): Limit the number of threads that can access a resource simultaneously.

    import java.util.concurrent.Semaphore;
    
    private final Semaphore semaphore = new Semaphore(5); // Allow 5 threads
    
    public void accessResource() throws InterruptedException {
        semaphore.acquire(); // Request permission
        try {
            // Work with resource
        } finally {
            semaphore.release(); // Release permission
        }
    }
    
  • Mutexes (Mutex): Although Java does not have a separate Mutex class, ReentrantLock is often used as a mutex (locked by only one thread).

  • Thread synchronization objects (java.util.concurrent)

    • CountDownLatch: Allows one or more threads to wait until a set of operations complete.

      import java.util.concurrent.CountDownLatch;
      
      private final CountDownLatch latch = new CountDownLatch(3); // Wait for 3 completions
      
      // Threads perform tasks and decrement the counter: latch.countDown();
      // Waiting thread: latch.await();
      
    • CyclicBarrier: Allows a group of threads to wait for each other at a certain point before continuing.

      import java.util.concurrent.CyclicBarrier;
      
      private final CyclicBarrier barrier = new CyclicBarrier(4); // Barrier for 4 threads
      
      // Threads perform tasks and reach the barrier: barrier.await();
      
    • Exchanger: Allows two threads to exchange objects at a synchronization point.

      import java.util.concurrent.Exchanger;
      
      private final Exchanger<String> exchanger = new Exchanger<>();
      
      // In one thread: String received = exchanger.exchange("Sending");
      // In another thread: String received = exchanger.exchange("Receiving");
      
  • Synchronized collections (Collections.synchronized...)

    • Wrap regular collections to make them thread-safe.
    • Example: Collections.synchronizedList(new ArrayList<>())
  • Thread-safe collections (java.util.concurrent)

    • Provide higher-performance and more flexible alternatives to synchronized collections.
    • Examples: ConcurrentHashMap, CopyOnWriteArrayList, BlockingQueue (e.g., ArrayBlockingQueue, LinkedBlockingQueue).

The choice of synchronization method depends on the specific task and requirements for performance and atomicity.