Concurrency
Concurrency tests thread creation, synchronization, visibility, executors, and concurrent collections.
Core rules
- Create a thread by extending
Threadand overridingrun(), or by passing aRunnabletoThread. Callstart(), notrun(), to create a new thread. Threadstates include NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED.synchronizedprovides mutual exclusion and visibility on the same lock object;wait(),notify(), andnotifyAll()must be called while holding that object's monitor.volatileguarantees visibility but not atomicity;AtomicIntegerand related classes provide atomic compound operations.ExecutorServicedecouples task submission from thread management.submit(Callable<T>)returnsFuture<T>;get()blocks and throwsExecutionExceptionwrapping the task's exception.- Concurrent collections (
ConcurrentHashMap,CopyOnWriteArrayList,BlockingQueue) are preferred over synchronized wrappers for concurrent access. shutdown()stops accepting tasks and lets queued tasks finish;shutdownNow()interrupts and returns queued tasks.
Worked example
ExecutorService ex = Executors.newSingleThreadExecutor();
Future<Integer> f = ex.submit(() -> 2 + 3);
int v = f.get();
ex.shutdown();
submit runs the Callable asynchronously; get() waits for completion and returns 5. If the callable threw, get() would throw ExecutionException whose cause is the original exception.
Traps
- Calling
run()directly executes on the current thread. - Synchronizing on different objects does not protect shared state.
Thread.sleep()does not release locks;wait()does.- A
Future.get()without a timeout can block forever. - Modifying a collection while iterating can throw
ConcurrentModificationException; use the iterator'sremove()or a concurrent collection. shutdownNow()does not guarantee immediate termination.