Reformat and clean up "net" package
This commit is contained in:
@@ -33,121 +33,120 @@ import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author RonanLana
|
||||
*
|
||||
* <p>
|
||||
* This tool has the main purpose of auditing deadlocks throughout the server and must be used only for debugging. The flag is USE_THREAD_TRACKER.
|
||||
*/
|
||||
public class ThreadTracker {
|
||||
private static ThreadTracker instance = null;
|
||||
|
||||
|
||||
public static ThreadTracker getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ThreadTracker();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
private final Lock ttLock = new ReentrantLock(true);
|
||||
|
||||
|
||||
private final Map<Long, List<MonitoredLockType>> threadTracker = new HashMap<>();
|
||||
private final Map<Long, Integer> threadUpdate = new HashMap<>();
|
||||
private final Map<Long, Thread> threads = new HashMap<>();
|
||||
|
||||
|
||||
private final Map<Long, AtomicInteger> lockCount = new HashMap<>();
|
||||
private final Map<Long, MonitoredLockType> lockIds = new HashMap<>();
|
||||
private final Map<Long, Long> lockThreads = new HashMap<>();
|
||||
private final Map<Long, Integer> lockUpdate = new HashMap<>();
|
||||
|
||||
|
||||
private final Map<MonitoredLockType, Map<Long, Integer>> locks = new HashMap<>();
|
||||
ScheduledFuture<?> threadTrackerSchedule;
|
||||
|
||||
|
||||
private String printThreadTrackerState(String dateFormat) {
|
||||
|
||||
|
||||
Map<MonitoredLockType, List<Integer>> lockValues = new HashMap<>();
|
||||
Set<Long> executingThreads = new HashSet<>();
|
||||
|
||||
for(Map.Entry<Long, AtomicInteger> lc : lockCount.entrySet()) {
|
||||
if(lc.getValue().get() != 0) {
|
||||
|
||||
for (Map.Entry<Long, AtomicInteger> lc : lockCount.entrySet()) {
|
||||
if (lc.getValue().get() != 0) {
|
||||
executingThreads.add(lockThreads.get(lc.getKey()));
|
||||
|
||||
|
||||
MonitoredLockType lockId = lockIds.get(lc.getKey());
|
||||
List<Integer> list = lockValues.get(lockId);
|
||||
|
||||
if(list == null) {
|
||||
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
lockValues.put(lockId, list);
|
||||
}
|
||||
|
||||
|
||||
list.add(lc.getValue().get());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
String s = "----------------------------\r\n" + dateFormat + "\r\n ";
|
||||
s += "Lock-thread usage count:";
|
||||
for(Map.Entry<MonitoredLockType, List<Integer>> lock : lockValues.entrySet()) {
|
||||
for (Map.Entry<MonitoredLockType, List<Integer>> lock : lockValues.entrySet()) {
|
||||
s += ("\r\n " + lock.getKey().name() + ": ");
|
||||
|
||||
for(Integer i : lock.getValue()) {
|
||||
|
||||
for (Integer i : lock.getValue()) {
|
||||
s += (i + " ");
|
||||
}
|
||||
}
|
||||
s += "\r\n\r\nThread opened lock path:";
|
||||
|
||||
for(Long tid : executingThreads) {
|
||||
|
||||
for (Long tid : executingThreads) {
|
||||
s += "\r\n";
|
||||
for(MonitoredLockType lockid : threadTracker.get(tid)) {
|
||||
for (MonitoredLockType lockid : threadTracker.get(tid)) {
|
||||
s += (lockid.name() + " ");
|
||||
}
|
||||
s += "|";
|
||||
}
|
||||
|
||||
|
||||
s += "\r\n\r\n";
|
||||
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
private static String printThreadLog(List<MonitoredLockType> stillLockedPath, String dateFormat) {
|
||||
String s = "----------------------------\r\n" + dateFormat + "\r\n ";
|
||||
for(MonitoredLockType lock : stillLockedPath) {
|
||||
for (MonitoredLockType lock : stillLockedPath) {
|
||||
s += (lock.name() + " ");
|
||||
}
|
||||
s += "\r\n\r\n";
|
||||
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
private static String printThreadStack(StackTraceElement[] list, String dateFormat) {
|
||||
String s = "----------------------------\r\n" + dateFormat + "\r\n";
|
||||
for (StackTraceElement stackTraceElement : list) {
|
||||
s += (" " + stackTraceElement.toString() + "\r\n");
|
||||
}
|
||||
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
public void accessThreadTracker(boolean update, boolean lock, MonitoredLockType lockId, long lockOid) {
|
||||
ttLock.lock();
|
||||
try {
|
||||
if(update) {
|
||||
if(!lock) { // update tracker
|
||||
if (update) {
|
||||
if (!lock) { // update tracker
|
||||
List<Long> toRemove = new ArrayList<>();
|
||||
|
||||
for(Long l : threadUpdate.keySet()) {
|
||||
for (Long l : threadUpdate.keySet()) {
|
||||
int next = threadUpdate.get(l) + 1;
|
||||
if(next == 4) {
|
||||
if (next == 4) {
|
||||
List<MonitoredLockType> tt = threadTracker.get(l);
|
||||
|
||||
if(tt.isEmpty()) {
|
||||
if (tt.isEmpty()) {
|
||||
toRemove.add(l);
|
||||
} else {
|
||||
StackTraceElement[] ste = threads.get(l).getStackTrace();
|
||||
if(ste.length > 0) {
|
||||
if (ste.length > 0) {
|
||||
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
|
||||
dateFormat.setTimeZone(TimeZone.getDefault());
|
||||
String df = dateFormat.format(new Date());
|
||||
|
||||
|
||||
FilePrinter.print(FilePrinter.DEADLOCK_LOCKS, printThreadLog(tt, df));
|
||||
FilePrinter.print(FilePrinter.DEADLOCK_STACK, printThreadStack(ste, df));
|
||||
}
|
||||
@@ -157,29 +156,29 @@ public class ThreadTracker {
|
||||
threadUpdate.put(l, next);
|
||||
}
|
||||
|
||||
for(Long l : toRemove) {
|
||||
for (Long l : toRemove) {
|
||||
threadTracker.remove(l);
|
||||
threadUpdate.remove(l);
|
||||
threads.remove(l);
|
||||
|
||||
for(Map<Long, Integer> threadLock : locks.values()) {
|
||||
for (Map<Long, Integer> threadLock : locks.values()) {
|
||||
threadLock.remove(l);
|
||||
}
|
||||
}
|
||||
|
||||
toRemove.clear();
|
||||
|
||||
for(Entry<Long, Integer> it : lockUpdate.entrySet()) {
|
||||
for (Entry<Long, Integer> it : lockUpdate.entrySet()) {
|
||||
int val = it.getValue() + 1;
|
||||
|
||||
if(val < 60) {
|
||||
if (val < 60) {
|
||||
lockUpdate.put(it.getKey(), val);
|
||||
} else {
|
||||
toRemove.add(it.getKey()); // free the structure after 60 silent updates
|
||||
}
|
||||
}
|
||||
|
||||
for(Long l : toRemove) {
|
||||
for (Long l : toRemove) {
|
||||
lockCount.remove(l);
|
||||
lockIds.remove(l);
|
||||
lockThreads.remove(l);
|
||||
@@ -195,9 +194,9 @@ public class ThreadTracker {
|
||||
} else {
|
||||
long tid = Thread.currentThread().getId();
|
||||
|
||||
if(lock) {
|
||||
if (lock) {
|
||||
AtomicInteger c = lockCount.get(lockOid);
|
||||
if(c == null) {
|
||||
if (c == null) {
|
||||
c = new AtomicInteger(0);
|
||||
lockCount.put(lockOid, c);
|
||||
lockIds.put(lockOid, lockId);
|
||||
@@ -207,40 +206,39 @@ public class ThreadTracker {
|
||||
c.incrementAndGet();
|
||||
|
||||
List<MonitoredLockType> list = threadTracker.get(tid);
|
||||
if(list == null) {
|
||||
if (list == null) {
|
||||
list = new ArrayList<>(5);
|
||||
threadTracker.put(tid, list);
|
||||
threadUpdate.put(tid, 0);
|
||||
threads.put(tid, Thread.currentThread());
|
||||
} else if(list.isEmpty()) {
|
||||
} else if (list.isEmpty()) {
|
||||
threadUpdate.put(tid, 0);
|
||||
}
|
||||
list.add(lockId);
|
||||
|
||||
Map<Long, Integer> threadLock = locks.get(lockId);
|
||||
if(threadLock == null) {
|
||||
if (threadLock == null) {
|
||||
threadLock = new HashMap<>(5);
|
||||
locks.put(lockId, threadLock);
|
||||
}
|
||||
|
||||
Integer lc = threadLock.get(tid);
|
||||
if(lc != null) {
|
||||
if (lc != null) {
|
||||
threadLock.put(tid, lc + 1);
|
||||
} else {
|
||||
threadLock.put(tid, 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
AtomicInteger c = lockCount.get(lockOid);
|
||||
if (c != null) { // thanks BHB for detecting an NPE here
|
||||
c.decrementAndGet();
|
||||
}
|
||||
|
||||
|
||||
lockUpdate.put(lockOid, 0);
|
||||
|
||||
List<MonitoredLockType> list = threadTracker.get(tid);
|
||||
for(int i = list.size() - 1; i >= 0; i--) {
|
||||
if(lockId.equals(list.get(i))) {
|
||||
for (int i = list.size() - 1; i >= 0; i--) {
|
||||
if (lockId.equals(list.get(i))) {
|
||||
list.remove(i);
|
||||
break;
|
||||
}
|
||||
@@ -254,25 +252,25 @@ public class ThreadTracker {
|
||||
ttLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String printLockStatus(MonitoredLockType lockId) {
|
||||
String s = "";
|
||||
|
||||
for(Long threadid : locks.get(lockId).keySet()) {
|
||||
for(MonitoredLockType lockid : threadTracker.get(threadid)) {
|
||||
|
||||
for (Long threadid : locks.get(lockId).keySet()) {
|
||||
for (MonitoredLockType lockid : threadTracker.get(threadid)) {
|
||||
s += (" " + lockid.name());
|
||||
}
|
||||
|
||||
|
||||
s += " |\r\n";
|
||||
}
|
||||
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
public void registerThreadTrackerTask() {
|
||||
threadTrackerSchedule = TimerManager.getInstance().register(() -> accessThreadTracker(true, false, MonitoredLockType.UNDEFINED, -1), 10000, 10000);
|
||||
}
|
||||
|
||||
|
||||
public void cancelThreadTrackerTask() {
|
||||
threadTrackerSchedule.cancel(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user