Java Concurrency In Practice (Part 1)

I highly recommend this book about Java concurrency. I extracted some of the main points from the book and will draft them out in this and the following blog posts.
When do you need synchronization:
- when multiple threads access the same mutable state variable
- don't share the state variable across threads (isolation)
- make the state variable immutable (immutability)
- use synchronization whenever accessing the state variable (locking)
COMPOUND ACTIONS NEED ATOMICITY:
BAD:
private long count = 0;
public long getCount() { return count; }
public void doSomething() {
blah blah
++count; // this contains 3 operations: read, increment, write
// they can be interrupted by other threads that see data in a bad state
}
GOOD:
private final AtomicLong count = new AtomicLong();
public long getCount() { return count.get(); }
public void doSomething() {
blah blah
count.incrementAndGet();
}
- If there are more variables that form an invariant, you need to update related state variables in a single atomic operation.
- if possible, try to use existing thread-safe objects, like AtomicLong to manage your class's state
RACE CONDITIONS
- Commonly found in check-then-act where a potentially stale observation is used to make a decision on what to do next.
- example of check-then-act: LAZY INITIALIZATION
private ExpensiveObject instance = null;
public ExpensiveObject getInstance() {
if (instance == null) // this line can be executed by two threads at the same time and two ExpensiveObjects will get
// newed. That will make getInstance() return two different intances
instance = new ExpensiveObject();
return instance;
}
Reader Comments