Deadlock and Livelock
A deadlock occurs when threads are blocked, with each thread wanting to access resources held by another thread simultaneously. It can be exemplified as follows: there are two threads, T1 and T2. T1 holds lock P, and T2 holds lock Q. T1 wants to acquire lock Q, which is held by T2, and T2 wants to acquire lock P, held by T1.
A livelock occurs when two threads perform actions in such a way that one action blocks the other, and vice versa. These two threads are dependent on each other, and as a result, the tasks executed by these threads cannot be completed. Unlike deadlock, the threads are not blocked, as the action of one thread responds to the action of the other thread and vice versa.