[Minor] Extended LockableObject to log owner of locks on lock timeout
This commit is contained in:
parent
2f1923218b
commit
51d8ff6d6c
|
@ -20,11 +20,10 @@ import static java.text.MessageFormat.format;
|
||||||
import static li.strolch.utils.helper.StringHelper.formatMillisecondsDuration;
|
import static li.strolch.utils.helper.StringHelper.formatMillisecondsDuration;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.Map;
|
import java.util.Collection;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import li.strolch.utils.helper.StringHelper;
|
|
||||||
import li.strolch.xmlpers.api.XmlPersistenceException;
|
import li.strolch.xmlpers.api.XmlPersistenceException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -38,12 +37,12 @@ public class LockableObject {
|
||||||
LockableObject.tryLockTime = tryLockTime;
|
LockableObject.tryLockTime = tryLockTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ReentrantLock lock;
|
private final Lock lock;
|
||||||
protected final String name;
|
protected final String name;
|
||||||
|
|
||||||
public LockableObject(String name) {
|
public LockableObject(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.lock = new ReentrantLock(true);
|
this.lock = new Lock(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
@ -69,19 +68,21 @@ public class LockableObject {
|
||||||
String msg = "Thread {0} failed to acquire lock after {1} for {2}"; //$NON-NLS-1$
|
String msg = "Thread {0} failed to acquire lock after {1} for {2}"; //$NON-NLS-1$
|
||||||
msg = format(msg, currentThread().getName(), formatMillisecondsDuration(tryLockTime), this);
|
msg = format(msg, currentThread().getName(), formatMillisecondsDuration(tryLockTime), this);
|
||||||
|
|
||||||
try {
|
Thread owner = lock.getOwner();
|
||||||
logger.error(msg);
|
if (owner == null) {
|
||||||
logger.error("Listing all active threads: ");
|
logger.error(MessageFormat.format("Lock {0} is currently held unknown thread!", this.name));
|
||||||
Map<Thread, StackTraceElement[]> allStackTraces = Thread.getAllStackTraces();
|
logger.error(lock.toString());
|
||||||
for (Thread thread : allStackTraces.keySet()) {
|
} else {
|
||||||
StackTraceElement[] trace = allStackTraces.get(thread);
|
Exception e = new Exception();
|
||||||
StringBuilder sb = new StringBuilder();
|
e.setStackTrace(owner.getStackTrace());
|
||||||
for (StackTraceElement traceElement : trace)
|
logger.error(MessageFormat.format("Lock {0} is currently held by {1}", this.name, owner), e);
|
||||||
sb.append("\n\tat ").append(traceElement);
|
}
|
||||||
logger.error("\nThread " + thread.getName() + ":\n" + sb.toString() + "\n");
|
|
||||||
}
|
logger.error("Threads waiting on this lock are:");
|
||||||
} catch (Exception e) {
|
for (Thread queuedThread : lock.getQueuedThreads()) {
|
||||||
logger.error("Failed to log active threads: " + e.getMessage(), e);
|
Exception e = new Exception();
|
||||||
|
e.setStackTrace(queuedThread.getStackTrace());
|
||||||
|
logger.error("\n" + queuedThread.getName(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new XmlPersistenceException(msg);
|
throw new XmlPersistenceException(msg);
|
||||||
|
@ -103,4 +104,21 @@ public class LockableObject {
|
||||||
this.lock.unlock();
|
this.lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class Lock extends ReentrantLock {
|
||||||
|
|
||||||
|
public Lock(boolean fair) {
|
||||||
|
super(fair);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Thread getOwner() {
|
||||||
|
return super.getOwner();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Thread> getQueuedThreads() {
|
||||||
|
return super.getQueuedThreads();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue