A data race occurs in concurrent programming when two or more threads access shared data at the same time, and at least one of the accesses is a write, leading to unpredictable and erroneous program behavior. Proper synchronization mechanisms, such as locks or atomic operations, are essential to prevent data races and ensure thread-safe operations.