Using multiple threads of execution within an application makes programming the application much more complicated. There’s the chance of corruption whenever one thread reads data that another thread is modifying, for example. Or threads may block with no chance of resuming their operation.
Concurrency issues are normally handled using monitors or semaphores. These facilities enable applications to control access to shared resources and to signal other threads when data is ready to be processed. Misuse of these constructs can lead to problems such as deadlock, however, so careful programming is needed to ensure that multithreaded programs work correctly and as expected.