Берегите ноги господа:
package wayerr.testlock;
import java.util.concurrent.locks.ReentrantLock;
public class TestLock {
private static final ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) throws Exception {
Thread thread = new Thread(() -> {
try {
recursion();
} catch(java.lang.StackOverflowError e) {
// it expected
}
});
thread.start();
thread.join();
System.out.println("Lock is locked: " + lock.isLocked());
if(lock.tryLock()) {
try {
System.out.println("OK");
} finally {
lock.unlock();
}
} else {
System.out.println("FAIL");
}
}
static final void recursion() {
lock.lock();
try {
recursion();
} finally {
lock.unlock();
}
}
}
В _этом_ тесте всегда выдает:
Lock is locked: true
FAIL
Чсх, на продакшене искать причину крайне весело, особенно с учетом того что в реальном коде он проявляться будет не всегда. Если метод recursion - не пустой то вероятность что стек кончится внутри lock - уменьшается.
зы. с каждым таким фокусом все больше любишь старый добрый synchronized .
ps. это починили в 9-ке: http://bugs.java.com/view_bug.do?bug_id=8046936 хотя известно с 11 года