Card 08/ 09
All 9 cards
ExerciseDifficulty: Advanced1 min
Four Classes: Which Are Safe and Which Only Look It
Four classes shared between threads. Decide for each whether it is safe, and if not, name the gap. All four before the reveal.
// 1
class A { private int n; synchronized void inc() { n++; } int get() { return n; } }
// 2
class B { private static int n; static synchronized void inc() { n++; }
synchronized int get() { return n; } }
// 3
class C { private final AtomicInteger n = new AtomicInteger();
void inc() { n.incrementAndGet(); } int get() { return n.get(); } }
// 4
class D { private final List<String> xs = Collections.synchronizedList(new ArrayList<>());
void addIfAbsent(String s) { if (!xs.contains(s)) { xs.add(s); } } }Which of the four are safe?
| Safe? | The gap | |
|---|---|---|
| 1 | No | get takes no lock, so it can read a value the last increment never published |
| 2 | No | inc locks the class and get locks the instance — two different locks |
| 3 | Yes | Both operations go through the atomic, which handles exclusion and visibility |
| 4 | No | contains and add are each atomic and the sequence between them is not |
Number two is the one that looks most thorough. Every method carries the keyword, and no two threads are ever excluded from each other, because the locks are different objects.
Number four is the shape from the previous exercise and from the money transfer. Where a class needs two calls to be one operation, the safety has to live in whoever is making them.