Unit 3 · Lesson 516 minAcademic review pending

When two threads touch the same data at once

Threads sharing memory is powerful and dangerous in the same breath. synchronized is how you say "only one thread may run this at a time," protecting shared data from being corrupted by simultaneous access.

Choose explanation

After this lesson

You should be able to

  • Explain a race condition and why shared mutable data causes one.
  • Use synchronized to protect a critical section.
  • Explain what a daemon thread is and why the JVM does not wait for it.
01

The race condition: two threads, one shared variable

Imagine two threads both incrementing the same counter variable. count++ looks like one operation, but it is really three: read the current value, add one, write the new value back. If both threads read the same starting value before either writes back, one increment is silently lost — the final count is wrong, and no exception was ever thrown to warn you.

This is a race condition: the correctness of the result depends on the unpredictable timing of two threads, something that never happened in any CS105ES or CS205ES program, because those programs only ever had one thread touching data at a time.

02

synchronized: one thread at a time, enforced

Marking a method synchronized means only one thread may execute it on a given object at a time — any other thread that calls it must wait until the first thread finishes. This directly fixes the counter race: with increment() synchronized, the read-add-write sequence always completes as one uninterrupted unit before another thread can start its own.

This safety has a real cost: synchronized threads waiting on each other cannot run in parallel during that wait, so overusing synchronized on code that did not need it slows the program down for no benefit. Synchronize only the specific section that actually touches shared, mutable data — not entire methods that happen to contain one risky line among many safe ones.

One keyword, protecting one shared field
class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;   // now safe: only one thread executes this at a time
    }

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

Daemon threads: background helpers the JVM does not wait for

By default, the JVM keeps running as long as any non-daemon thread is still alive, even if the main method has finished. A daemon thread, marked with setDaemon(true) before it is started, is different: the JVM exits the moment every remaining thread is a daemon, without waiting for daemon threads to finish, even mid-task.

Daemon threads suit background housekeeping that should never block the program from shutting down — like a periodic cleanup task — precisely because the program's actual purpose does not depend on that task ever completing. A file-writing thread should almost never be a daemon, because losing it mid-write would silently lose data; the choice is a deliberate statement about whether the thread's work is essential to keep at all costs.

Try it yourself

Take the Counter class above and imagine synchronized was removed from increment(). Write two sentences: one describing the race condition that becomes possible, and one describing exactly which three sub-steps of count++ could interleave badly between two threads.

Need a hint?

The three sub-steps are read, add one, write back — interleaving happens when one thread's read happens before another thread's write.

Check the worked solution

Without synchronized, two threads could both read the same value of count before either writes back, so one thread's increment is silently overwritten by the other's — the final count is one lower than the number of increments actually performed, with no error or exception to reveal it.

Quick check

Why does marking increment() synchronized fix the race condition on the count field?

Select an answer to check your thinking.

Why this lesson exists

Syllabus mapping

synchronizing threads, inter thread communication, thread groups, daemon threads.

Maps to course outcome CO3.