A race condition is a concurrency defect whose outcome depends on competing threads’ timing when they access the same resource. Without synchronization, interleaved operations can produce exceptions, stopped threads, or threads that remain alive while doing nothing. section 5.2.2
A producer-consumer example shares an ArrayList between two producers and two consumers. Each checks size and then changes the list, leaving the check-and-change sequence vulnerable to interference.
Diagnose the failure with VisualVM: inspect CPU and memory activity, then examine live thread states and a thread dump. An exception such as ArrayIndexOutOfBoundsException can stop several threads, while zombie threads may keep the process active.
Correct the defect by synchronizing both producer and consumer access to the list, keeping each size check and mutation inside the same synchronized block. The monitor admits one thread at a time.



















