Sobes.tech
Middle

What are the basic synchronization methods in Java?

sobes.tech AI

Answer from AI

Main basic synchronization methods in Java:

  1. Keyword synchronized:

    • Used for synchronizing methods or code blocks.
    • A method marked synchronized blocks access to the instance of the object for other synchronized methods of the same object.
    • synchronized (this): synchronization on the current object instance.
    • synchronized (ClassName.class): class-level synchronization, blocks access for all threads working with this class.
    • synchronized (object): synchronization on a specific monitor object.
    class Counter {
        private int count = 0;
    
        // Synchronized method
        public synchronized void increment() {
            count++;
        }
    
        public void decrement() {
            // Synchronized block
            synchronized (this) {
                count--;
            }
        }
    }
    
  2. Keyword volatile:

    • Ensures visibility of variable changes between threads.
    • Does not guarantee atomicity of complex operations (e.g., i++), only read and write.
    • Applied to class fields.
    class SharedData {
        volatile boolean flag = false;
    
        public void setFlag(boolean value) {
            flag = value; // Changing the flag becomes visible to other threads
        }
    
        public boolean getFlag() {
            return flag;
        }
    }
    
  3. Explicit Locks:

    • Provide more flexible control compared to synchronized.
    • Interface Lock and its implementations, such as ReentrantLock.
    • Allow choosing between fair and unfair locking modes, obtaining lock state, interrupting threads while waiting for a lock.
    • Require explicit calls to lock() and unlock(). It is important to use a finally block to call unlock().
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    class Resource {
        private final Lock lock = new ReentrantLock();
    
        public void performAction() {
            lock.lock(); // Acquire lock
            try {
                // Critical section
                System.out.println(Thread.currentThread().getName() + " acquired lock");
                Thread.sleep(100); // Simulate work
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                lock.unlock(); // Release lock
                System.out.println(Thread.currentThread().getName() + " released lock");
            }
        }
    }
    
  4. wait(), notify(), notifyAll():

    • Methods of the Object class, used for thread interaction, waiting for monitor release.
    • wait(): releases the monitor and puts the thread into waiting state until notify() or notifyAll() is called.
    • notify(): wakes up one thread waiting on this monitor.
    • notifyAll(): wakes up all threads waiting on this monitor.
    • Must be called within a synchronized block or method for the same monitor object.
    class ProducerConsumer {
        private final Object monitor = new Object();
        private boolean isProduced = false;
    
        public void produce() throws InterruptedException {
            synchronized (monitor) {
                while (isProduced) {
                    monitor.wait(); // Wait until consumer consumes
                }
                // Produce
                System.out.println("Produced");
                isProduced = true;
                monitor.notifyAll(); // Notify consumers
            }
        }
    
        public void consume() throws InterruptedException {
            synchronized (monitor) {
                while (!isProduced) {
                    monitor.wait(); // Wait until producer produces
                }
                // Consume
                System.out.println("Consumed");
                isProduced = false;
                monitor.notifyAll(); // Notify producers
            }
        }
    }
    

These mechanisms are the foundation for creating thread-safe Java code. The choice of a specific method depends on the task's specifics and the required level of synchronization control.