package ex7; import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.LongAdder; public final class Profiler { private static final class MonitorEntry { private final int hashCode; private final String name; public MonitorEntry(int hashCode, String name) { this.hashCode = hashCode; this.name = name; } public int getHashCode() { return hashCode; } public String getName() { return name; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; MonitorEntry that = (MonitorEntry) o; return hashCode == that.hashCode && Objects.equals(name, that.name); } @Override public int hashCode() { return Objects.hash(hashCode, name); } } private static final Map monitorToAccessCount = new ConcurrentHashMap<>(); static { Runtime.getRuntime().addShutdownHook(new Thread(() -> { for (final var entry : monitorToAccessCount.entrySet()) { System.out.printf("%d - %s - #Locks: %d%n", entry.getKey().getHashCode(), entry.getKey().getName(), entry.getValue().intValue() ); } })); } private Profiler() { } public static void countMonitorAccess(final Object obj) { final MonitorEntry monitorEntry = new MonitorEntry(obj.hashCode(), obj.getClass().getName()); monitorToAccessCount.computeIfAbsent(monitorEntry, k -> new LongAdder()); monitorToAccessCount.get(monitorEntry).increment(); } }