synchronized
Lets only one thread at a time run a block of code.
Available since: Java 1.0
Syntax
synchronized void method() { ... }
synchronized (lock) { ... }Examples
A safe counter:
class Counter {
private int value;
synchronized void increment() {
value++;
}
synchronized int get() {
return value;
}
}
void main() throws InterruptedException {
var counter = new Counter();
Runnable task = () -> { for (int i = 0; i < 10_000; i++) counter.increment(); };
Thread a = new Thread(task), b = new Thread(task);
a.start(); b.start();
a.join(); b.join();
IO.println(counter.get());
}Output:
20000A block with a separate lock object:
void main() throws InterruptedException {
Object lock = new Object();
List<Integer> shared = new ArrayList<>();
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
synchronized (lock) {
shared.add(i);
}
}
};
Thread a = new Thread(task), b = new Thread(task);
a.start(); b.start();
a.join(); b.join();
IO.println(shared.size());
}Output:
2000Notes
Without synchronized the value++ operation from two threads loses updates, and the result is usually less than 20000. A synchronized instance method locks this, a static one locks the class. Inside the block, changes another thread made before leaving its block are guaranteed to be visible.
See also
- ReentrantLock — An explicit lock — a flexible replacement for `synchronized`.
- AtomicInteger — An integer that can be changed safely from several threads without locks.
- volatile — Marks a field whose changes are immediately visible to all threads.
Related recipes
In the tutorial
- Synchronization — Race conditions in Java and how to avoid them — synchronized methods and blocks, atomic classes like AtomicInteger, ReentrantLock and a shared lock object.