1 package jdk.internal.misc; 2 3 import java.util.Arrays; 4 import java.util.function.Consumer; 5 6 public class JdkThreadLocal<T> extends ThreadLocal<T> { 7 protected void threadTerminated(T value) { 8 } 9 10 public void callThreadTerminated(Object value) { 11 @SuppressWarnings("unchecked") 12 final T v = (T) value; 13 threadTerminated(v); 14 } 15 16 public JdkThreadLocal() { 17 add(this); 18 } 19 20 private static final class Entry<U> { 21 private final JdkThreadLocal<U> threadLocal; 22 23 private Entry(JdkThreadLocal<U> threadLocal) { 24 this.threadLocal = threadLocal; 25 } 26 27 public JdkThreadLocal<U> threadLocal() { 28 return threadLocal; 29 } 30 } 31 32 private static volatile Entry<?>[] entries = new Entry<?>[0]; 33 34 private static synchronized <U> void add(JdkThreadLocal<U> threadLocal) { 35 if (threadLocal == null) { 36 throw new IllegalArgumentException("threadLocal is null"); 37 } 38 forEach(tl -> { 39 if (tl == threadLocal) { 40 throw new IllegalArgumentException("threadLocal has already been added"); 41 } 42 }); 43 44 final Entry<U> entry = new Entry<>(threadLocal); 45 final Entry<?>[] entries0 = Arrays.copyOf(entries, entries.length + 1); 46 entries0[entries0.length - 1] = entry; 47 entries = entries0; 48 } 49 50 public static void forEach(Consumer<JdkThreadLocal<?>> f) { 51 final Entry<?>[] entries0 = entries; 52 for (Entry<?> e: entries0) { 53 final JdkThreadLocal<?> tl = e.threadLocal(); 54 f.accept(tl); 55 } 56 } 57 }