Java.Multithreading.Is there a way to solve a race condition?

Yes, there are multiple ways to solve a race condition depending on what you’re doing and how critical performance is.

Let’s go over the most common and effective ways 🔧:


🛠️ 1. Use synchronized

This is the most straightforward way to make a block or method thread-safe.

Example:

class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++; // now thread-safe
    }

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

synchronized ensures only one thread can access that code at a time.

It also establishes visibility (thread sees the latest value).

⚙️ 2. Use AtomicInteger (Lock-free, efficient)

If you’re dealing with simple operations on a single variable, use Java’s atomic classes.

import java.util.concurrent.atomic.AtomicInteger;

class Counter {
    private final AtomicInteger count = new AtomicInteger(0);

    public void increment() {
        count.incrementAndGet(); // atomic & thread-safe
    }

    public int getCount() {
        return count.get();
    }
}

Behind the scenes: uses CAS (Compare-And-Swap).

Great for counters, flags, or sequences.

🧱 3. Use ReentrantLock for Fine-Grained Control

If you need flexible locking, like:

  • Try-lock with timeout
  • Fair locking
  • Unlocking in different places
import java.util.concurrent.locks.ReentrantLock;

class Counter {
    private int count = 0;
    private final ReentrantLock lock = new ReentrantLock();

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock(); // always release!
        }
    }

    public int getCount() {
        return count;
    }
}

🧪 4. Use volatile (Visibility only – not for compound actions!)

If your issue is visibility, not atomicity (e.g. flags), you can use volatile.

volatile boolean running = true;

⚠️ But volatile is not safe for things like x++!

💡 Bonus: Higher-Level Solutions

ToolUse Case
ConcurrentHashMapThread-safe key-value storage
CopyOnWriteArrayListThread-safe list with few writes
ExecutorServiceAvoid managing threads manually
Semaphore, CountDownLatch, CyclicBarrierCoordinate threads

🧠 Summary Table

MethodAtomic?Visible to Threads?Best For
synchronized✅ Yes✅ YesCritical sections, simple sync
AtomicInteger✅ Yes✅ YesCounters, simple operations
ReentrantLock✅ Yes✅ YesAdvanced locking scenarios
volatile❌ No✅ YesFlags, stop signals
This entry was posted in Без рубрики. Bookmark the permalink.