Threads · Topic 7 of 7
Deadlock
Definition​
A deadlock happens when two threads each hold a lock the other one needs, so both wait forever. You avoid it by always taking locks in the same order, or by using tryLock with a timeout so a thread can give up.
Example code​
Two threads that would deadlock, saved by a timeout
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
class Demo {
static final ReentrantLock lockA = new ReentrantLock();
static final ReentrantLock lockB = new ReentrantLock();
static final CountDownLatch bothHoldOne = new CountDownLatch(2);
static final AtomicInteger gaveUp = new AtomicInteger();
static void work(ReentrantLock first, ReentrantLock second) {
first.lock();
try {
bothHoldOne.countDown();
bothHoldOne.await(); // make sure both threads hold one lock
if (second.tryLock(200, TimeUnit.MILLISECONDS)) { // with plain lock() this would hang forever
second.unlock();
} else {
gaveUp.incrementAndGet(); // gave up instead of waiting forever
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
first.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> work(lockA, lockB)); // A then B
Thread t2 = new Thread(() -> work(lockB, lockA)); // B then A: the opposite order
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("threads that gave up: " + gaveUp.get());
// fix: always take the locks in the same order (A then B) in every thread
}
}
// Output:
// threads that gave up: 1
Finished this page? Track your progress (saved only in your browser).