猎祖猎宗 发表于 2020-11-26 15:41

关于ThreadLocal的问题

private static ThreadLocal<Project> project = ThreadLocal.withInitial(()->new Project());public static void main(String[] args) throws ParseException, InterruptedException {
    new Thread(()-> {
      try {
            Project sdf = project.get();
            //Thread.sleep(10L);
            sdf.setCompany("啊");
            System.out.println(sdf+"----" + Thread.currentThread().getId());
            sdf.setCompany("C");
            System.out.println(sdf+"----" + Thread.currentThread().getId());
      } catch (Exception e) {
      }
    }).start();
    new Thread(()-> {
      try {
            Project sdf = project.get();
            sdf.setCompany("啊");
            System.out.println(sdf+"----" + Thread.currentThread().getId());
      } catch (Exception e) {
      }
    }).start();
    new Thread(()-> {
      try {
            Project sdf = project.get();
            System.out.println(sdf+"----" + Thread.currentThread().getId());
      } catch (Exception e) {
      }
    }).start();

    while (true);

}输出结果com.lzy.demo.ProjectDto.Project@141f979companynull----14com.lzy.demo.ProjectDto.Project@1424e98company啊----13com.lzy.demo.ProjectDto.Project@1424e98company啊----12com.lzy.demo.ProjectDto.Project@141f991companyC----12
请问为什么当我Project实体里面的值相同时,对象地址相同,而company发生改变是线程12里面指向的地址发生了变化,这块搞不太懂,有大佬帮忙解答一下吗

猎祖猎宗 发表于 2020-11-26 15:42

输出结果

Vvvvvoid 发表于 2020-11-26 17:46

ThreadLocal 的作用是 单个线程内执行多个方法 可以做到参数共享

你创建了三个 线程, 每个线程里的 ThreadLocal 初始化都会 创建一个 Project 对象, 所以一共会创建 三个 对象

每个线程的 id 都是不同的 , 所以有三个线程ID , 而且 每个线程ID 对应的 Project 对象ID 是 不会变的

不夏流年 发表于 2020-11-26 19:03

问题都没说清楚,线程起个名字很难么

猎祖猎宗 发表于 2020-11-27 10:12

private static ThreadLocal<SimpleDateFormat> threadLocal = ThreadLocal.withInitial(()->new SimpleDateFormat("yyyy"));
    private static Object a,b,c;
    public static void main(String[] args) throws ParseException, InterruptedException {
      Thread threadA = new Thread(()->{
            Object object = threadLocal.get();
            a= object;
            System.out.println("线程名:"+Thread.currentThread().getName()+",输出结果"+object);
      });
      threadA.setName("A");

      Thread threadB = new Thread(()->{
            Object object = threadLocal.get();
            b = object;
            System.out.println("线程名:"+Thread.currentThread().getName()+",输出结果"+object);
      });
      threadB.setName("B");

      Thread threadC = new Thread(()->{
            Object object = threadLocal.get();
            c=object;
            System.out.println("线程名:"+Thread.currentThread().getName()+",输出结果"+object);
      });
      threadC.setName("C");
      threadA.start();
      threadB.start();
      threadC.start();
      threadA.join();
      threadB.join();
      threadC.join();
      System.out.println(b==c);
      System.out.println(c==a);
      System.out.println(a==b);
    }
输出结果线程名:A,输出结果java.text.SimpleDateFormat@38d640
线程名:C,输出结果java.text.SimpleDateFormat@38d640
线程名:B,输出结果java.text.SimpleDateFormat@38d640
false
false
false

输出的结果调用toString,由于重写了SimpleDateFormat(问题中提到的Project对象同理)hashcode,看到    线程ABC输出结果java.text.SimpleDateFormat@38d640都是一样的,
但是通过把对象赋值 abc三个静态变量,然后发现 全是false,
//SimpleDateFormat的hashCode
//实际为调用String的hashCode
public class SimpleDateFormat extends DateFormat {
private String pattern;
@Override
    public int hashCode()
    {
      return pattern.hashCode();
      // just enough fields for a reasonable distribution
    }
}
页: [1]
查看完整版本: 关于ThreadLocal的问题