Implementing Threads in applications is not an ardous task.
Tasks can divided implemented in independent threads and the threads can be scaled along with the number of CPU cores.
The problem comes when those threads need to interact with each other. And this is something which is more common in real world projects than you would imagine.
When they require exchanging some information. This requires allocation of space in RAM that is accessible to both threads.
And this is the root of many of the much talked about problems in parallel programming.
The first and one of the biggest of these is called race condition. This comes due to undefined access order. We can get incorrect results from calculations due because multiple threads can access and read or write the shared variables in an unpredictable order.