More on Thread Safety CSE451 Andrew Whitaker
Review: Thread Hazards Safety hazards “Program does the wrong thing” Liveness hazards “Program never does the right thing” e.g., deadlock Performance hazards Program is too slow due to excessive synchronization
Safety Rule #1 All shared, mutable state must be properly synchronized Usually with a synchronized block or method
Why Not Make Every Method Synchronized? Synchronization has a performance cost Each lock access is a cache miss Synchronization limits parallelism Rampant synchronization leads to deadlock Available parallelism Amount of synchronization
Safety Rule #1, Revised All shared, mutable state must be properly synchronized Usually with a synchronized block or method Corollaries: Do not synchronize for non-shared state Accessed by a single thread Do not synchronize on immutable state
public class Foo { public int addSix(int arg) { synchronized (this) { arg += 6; } return arg; } This is unnecessary! No need to synchronize on non-shared state.
// Thread-safe public class Integer { private final int x; public Integer(int arg) { this.x = arg; } public synchronized int get() { return x; } Immutable state does not require synchronization!
Example from Project #1 Do the execcounts counters require synchronized access? Technically, yes: The counters are shared across multiple processes/threads The counters are mutable Solution: atomic variables See Linux /include/asm-i386/atomic.h You do not need to do this for project #1
Another Example: AspectRatio
Rule #2 Compound actions must be protected by a single lock Often, we talk about protecting an invariant with a single lock e.g., aspect ratio remains fixed
Linked List Example