package ex8; import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.LongAdder; public final class Profiler { private record Invocation(String threadName, String invokeType) { @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Invocation that = (Invocation) o; return Objects.equals(threadName, that.threadName) && Objects.equals(invokeType, that.invokeType); } @Override public int hashCode() { return Objects.hash(threadName, invokeType); } } private Profiler() { } private static final Map invocationToCount = new ConcurrentHashMap<>(); // TODO change format to match assignment static { Runtime.getRuntime().addShutdownHook(new Thread(() -> { for (final var entry : invocationToCount.entrySet()) { System.out.printf("Thread: %s Type: %s Count: %d%n", entry.getKey().threadName, entry.getKey().invokeType, entry.getValue().intValue() ); } })); } public static void countInvoke(final String threadName, final String invokeType) { final Invocation invocation = new Invocation(threadName, invokeType); invocationToCount.computeIfAbsent(invocation, k -> new LongAdder()); invocationToCount.get(invocation).increment(); } }