今天看了一下ThreadLocal的东西,网上的都是大同小异,大致都如这篇文章:

ThreadLocal详解

觉得很多地方写的都很难理解,整理一下思路,写个简单的。
ThreadLocal是一个类,而且是java.lang下的,所以可以直接使用,而不用专门去import。
 
ThreadLocal类里有一个map结构,这个map的key是Thread对象,而value则是Object类型。这就是说,我们可以利用这个map存储任何对象。
ThreadLocal提供了,set(Object o)和get()方法。set(Object o)用于往自己的map结构类添加对象,而get()则是从map中取对象。那么为什么没有key这个参数呢,set(Object o)和get()方法,为key这样赋值,key = Thread.CurrentThred()。
所以set(Object object)和get()方法都没有key这个参数。
 
这种机制保证了每个当前线程都可以有自己的一个key-value的值对存储在ThreadLocal中。
 
测试的例子:
首先,我们得知道,ThreadLocal是为多个Thread服务的,而且这些Thread是共享这个ThreadLocal的。如果不是共享的话,那么map结构就失去了意义。
 
定义一个类,将ThreadLocal作为其static属性。
public class Test implements Runnable {
   private static ThreadLocal threadLocal = new ThreadLocal() {
     protected synchronized Integer initialValue() {
       return new Integer(0);
    }
  };

   public int get() {
     return threadLocal.get();
  }

   public void set() {
    threadLocal.set( new Integer(threadLocal.get() + 1));
  } 
 
 public void run() {
 }
}
 
 
 
threadLocal这个静态属性创建时,覆写了initialValue()方法。该方法用于为当前线程设置默认value,即key = Thread.currentThread(),value=0。该方法在第一次调用get()方法时使用。也就是说,对于当前线程,还没有set(Object object)被调用过,map里没有当前线程的key。
 
Test.set(Object)和Test.get()是对ThreadLocal的对应set(Object)和get()方法的一个包装。
 
那么如何证明每个Thread的各自的状态都是独立保存的呢?
 
首先打印出多个进程运行时的状态。
 
 
 
 
 
 

 
public class Test implements Runnable {
   private static ThreadLocal threadLocal = new ThreadLocal() {
     protected synchronized Integer initialValue() {
       return new Integer(0);
    }
  };

   public int get() {
     return threadLocal.get();
  }

   public void set() {
    threadLocal.set( new Integer(threadLocal.get() + 1));
  }

   public void run() {
    System.out.println(Thread.currentThread() + "=====" + get());
  }

   public static void main(String[] args) {
    Test test = new Test();

    Thread thread1 = new Thread(test);
    Thread thread2 = new Thread(test);
    Thread thread3 = new Thread(test);

    thread1.start();
    thread2.start();
    thread3.start();
  }
}
打印结果如下:
Thread[Thread-0,5,main]=====0
Thread[Thread-1,5,main]=====0
Thread[Thread-2,5,main]=====0
从以上结果,无法看出三个Thread的状态是否独立保存。因为三个值相同,所以不能判断三者取的是同一个变量,还是多个变量。
 
在run()方法中进行循环,将ThreadLocal保存的信息顺次加1。如果三者使用是同一变量,那么将会出现1、2、3、4……
 
public class Test implements Runnable {
   private static ThreadLocal threadLocal = new ThreadLocal() {
     protected synchronized Integer initialValue() {
       return new Integer(0);
    }
  };

   public int get() {
     return threadLocal.get();
  }

   public void set() {
    threadLocal.set( new Integer(threadLocal.get() + 1));
  }

  public void run() {
    for (int i=0; i<3; i++) {
      System.out.println(Thread.currentThread() + "=====" + get());
      set();
    }
  }


   public static void main(String[] args) {
    Test test = new Test();

    Thread thread1 = new Thread(test);
    Thread thread2 = new Thread(test);
    Thread thread3 = new Thread(test);

    thread1.start();
    thread2.start();
    thread3.start();
  }
}
 
打印出的结果如下所示。
Thread[Thread-0,5,main]=====0
Thread[Thread-0,5,main]=====1
Thread[Thread-0,5,main]=====2
Thread[Thread-1,5,main]=====0
Thread[Thread-1,5,main]=====1
Thread[Thread-1,5,main]=====2
Thread[Thread-2,5,main]=====0
Thread[Thread-2,5,main]=====1
Thread[Thread-2,5,main]=====2
 
可见,各Thread的状态是相互独立的。