package jdk.internal.misc; import java.util.Arrays; import java.util.function.Consumer; public class JdkThreadLocal extends ThreadLocal { protected void threadTerminated(T value) { } public void callThreadTerminated(Object value) { @SuppressWarnings("unchecked") final T v = (T) value; threadTerminated(v); } public JdkThreadLocal() { add(this); } private static final class Entry { private final JdkThreadLocal threadLocal; private Entry(JdkThreadLocal threadLocal) { this.threadLocal = threadLocal; } public JdkThreadLocal threadLocal() { return threadLocal; } } private static volatile Entry[] entries = new Entry[0]; private static synchronized void add(JdkThreadLocal threadLocal) { if (threadLocal == null) { throw new IllegalArgumentException("threadLocal is null"); } forEach(tl -> { if (tl == threadLocal) { throw new IllegalArgumentException("threadLocal has already been added"); } }); final Entry entry = new Entry<>(threadLocal); final Entry[] entries0 = Arrays.copyOf(entries, entries.length + 1); entries0[entries0.length - 1] = entry; entries = entries0; } public static void forEach(Consumer> f) { final Entry[] entries0 = entries; for (Entry e: entries0) { final JdkThreadLocal tl = e.threadLocal(); f.accept(tl); } } }