package Test0814;
import com.google.common.collect.Maps;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
public class MyThreadLocal<T> extends InheritableThreadLocal<T> {
//方法1
public static final InheritableThreadLocal<MyThreadLocal<Object>> mapThreadLocal=new InheritableThreadLocal<>();
//方法2
public static final Map<Thread,MyThreadLocal<Object>> maps= Maps.newConcurrentMap();
public MyThreadLocal(){
super();
}
@Override
public void set(T t){
super.set(t);
//set的时候降当前对象存储到map或者threadlocal,然后再实力化包装的runnable的时候,需要拿到当前对象和值 赋给RunnableWrapper ,以便带给任务内的代码获取父线程的值
this.addThis();
maps.put(Thread.currentThread(),(MyThreadLocal<Object>) this);
}
@Override
public T get(){
return super.get();
}
private void addThis(){
mapThreadLocal.set((MyThreadLocal<Object>) this);
}
public static class TransInner{
public static MyThreadLocal<Object> getCap(){
MyThreadLocal<Object> parentLocalMap=mapThreadLocal.get();
return parentLocalMap;
}
}
}
package Test0814;
import java.util.Map;
import java.util.logging.Logger;
// 包装的Runnable,以便将父线程的值传到子线程内
public class RunableWrapper implements Runnable {
private Runnable runnable;
private Object parentMapValue=null;
private MyThreadLocal myThreadLocal=MyThreadLocal.maps.get(Thread.currentThread()); //获取父线程的ThreadLocal对象,也可以写在构造器内
public static RunableWrapper getRunnable(Runnable runnable){
return new RunableWrapper(runnable);
}
public RunableWrapper() {
}
public RunableWrapper(Runnable runnable){
this.runnable=runnable;
this.parentMapValue=myThreadLocal.get();//获取父对象TTL的值
// this.parentMapValue=myThreadLocal.get();
// this.myThreadLocal=myThreadLocal;
}
@Override
public void run() {
// System.out.println("p="+parentMapValue);
// System.out.println("myThreadLocal="+myThreadLocal);
myThreadLocal.set(parentMapValue); //将父线程的值写入子线程,这样在执行run方法的时候就能获取 父线程的值了
runnable.run();
myThreadLocal.remove();//用完后remove 防止内存泄漏
}
}
package Test0814;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @Auther: qint
* @Date: 2023/08/14 11:15
* @Description:
*/
public class Main2 {
private static MyThreadLocal threadLocal = new MyThreadLocal();
private static ExecutorService ES = Executors.newFixedThreadPool(1);
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
final int a = i;
ES.submit(() -> {
Thread.currentThread().setName("儿子线程" + a);
String parentName = Thread.currentThread().getName();
threadLocal.set(parentName);
System.out.println("儿子线程的ThreadLocal:" + threadLocal.get());
ES.submit(RunableWrapper.getRunnable(() -> {
Thread.currentThread().setName(parentName + " 的儿子线程");
System.out.println(parentName + "的儿子线程的ThreadLocal:" + threadLocal.get());
}));
}
);
}
}
}