package ex9; import java.util.LinkedList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; public final class Profiler { private static final ConcurrentMap> callLog = new ConcurrentHashMap<>(); static { Runtime.getRuntime().addShutdownHook(new Thread(Profiler::print)); } private Profiler() { } public static void logCall(final Thread thread, final String methodName) { final List list = callLog.computeIfAbsent(thread, ignored -> new LinkedList<>()); // thread safe, as once a thread accesses its own list access to said list is non-concurrent list.add(methodName); } private static void print() { for (final Thread thread : callLog.keySet()) { System.out.printf("=== %s ===\n", thread.getName()); callLog.get(thread).forEach(System.out::println); } } }