Java中线程的问题:明明是同一个thread对象,但是threadLocal不是同一个

package hub;
/*为啥不同线程中的ThreadLocal是互相独立的。 明明是同一个thread对象

  • 打印出来的结果 在主线程里面是var2 ,在thread线程中是var1
    */
    public class ThreadLocalUsage extends Thread {
    public User user = new User();

    public User getUser() {
    return user;
    }

    @Override
    public void run() {
    this.user.set("var1");

    while (true) {
        try {
            sleep(1000);
        } catch (InterruptedException e) {
        }
        System.out.println(this.user.get());
    }
    

    }

    public static void main(String[] args) {

    ThreadLocalUsage thread = new ThreadLocalUsage();
    thread.start();
    
    try {
        sleep(4000);
    } catch (InterruptedException e) {
    }
    
    thread.user.set("var2");
    System.out.println(thread.user.get());
    

    }
    }

class User {

private static ThreadLocal<Object> enclosure = new ThreadLocal<Object>(); // is it must be static?

public void set(Object object) {
    enclosure.set(object);
}

public Object get() {
    return enclosure.get();
}

}

上面这个代码明明是一个thread对象,怎么打印出来的threadlocal的值不一样,也就是代表不是同一个threadlocal

你理解错了,不是同一个thread对象,而是同一个ThreadLocal enclosure对象,即thread.user.enclosure对象。
你是两个线程中分别set到ThreadLocal对象的key是某个线程,值是线程设置的值。
你可以打印当前线程+线程设置的值,可以看到你的代码中有两个线程对象main和ThreadLocalUsage两个线程,它们存储在同一个ThreadLocal变量中。修正测试代码如下:

    public void run() {
        this.user.set("var1");
        while (true) {
            try {
                sleep(1000);
            } catch (InterruptedException e) {
            }
            System.out.println(Thread.currentThread().getName()+":"+this.user.get());
        }

    }

    public static void main(String[] args) {
        ThreadLocalUsage thread = new ThreadLocalUsage();
        thread.start();

        try {
            sleep(4000);
        } catch (InterruptedException e) {
        }

        thread.user.set("var2");
        System.out.println(Thread.currentThread().getName()+":"+thread.user.get());

    }

测试就可以看到这是两个不同线程的值。

ThreadLocal对象本质类似一个以线程对象为key的哈希表,它能使线程中的某个值与保存值的线程对象关联起来。
所以上述你是两个线程中分别调用了同一个ThreadLocal对象的set方法,所以get方法返回的是当前线程set的值。各个线程中的get的值对应其set的值,所以结果是:

 Thread-0:var1
main:var2
Thread-0:var1

两个线程取到的get值各是各的,当然是两个值了。

ThreadLocalUsage thread = new ThreadLocalUsage();
thread.start();
这个地方是这个线程启动的地方
thread.user.set("var2"); 这边是对这个现场的user变量设置值,这个不是应该是同一个线程对象吗