Let's assume the case a shared resource is an space in memory, and the data stored in this space can be accessed by two or more threads (access to this memory is a critical section).
If the corresponding synchronization methods among threads are not implemented, the data in this shared memory when it is used by some thread can be modified at any given time by another thread: this is a race condition.
Example of race condition: Let's say that global variable var is used by thread1 and thread2. Thread1 assign value 3 to var for using this later. In the meanwhile thread2 assign the value 4 to var. When thread1 come back and use var for using value 3, it uses it regardless its value is now 4.
Race conditions are avoided by implementing proper synchronization mechanisms as mutex, semaphores or spin locks.