With a deadlock, there are two or more threads: each thread holds one lock, and needs to acquire another lock. Each thread is sleeping on the lock the other thread holds. Because they are asleep, they are 'dead' -- not executing any code, and they never will.
With a livelock, two or more threads are alive and executing code, but they cannot continue past conditions in their code because they are too busy responding to events from other threads in the livelock.
My Java is seriously rusty at this point, so let's go with a hopefully-simple description:
Two threads, A
and B
, need to acquire locks 1
and 2
in order to perform some operation (eating a sandwich):
Thread A tries this:
Acquire lock 1
if try_lock(2) == success
eat the sandwich
else
drop 1
sleep a bit
go back to start
Thread B tries this:
Acquire lock 2
if try_lock(1) == success
eat the sandwich
else
drop 2
sleep a bit
go back to start
If these two threads always alternate instructions, neither one will ever eat
the sandwich: they will both spend all their time acquiring, testing, and
dropping locks, but they never get to make forward progress.