ThreadLocal
其实 ThreadLocal 并非是一个线程的本地实现,它并不是一个 Thread ,而是 Thread Local Variable(线程局部变量),它的功能就是为每一个使用该变量的线程 提供一个变量值的副本,每一个线程都可以独立地改变自己的副本而不影响其它线程。从线程的角度来看,就好像没一个线程都完全拥有该变量。
ThreadLocal 与其它线程同步机制的区别
ThreadLocal 与其它同步机制都是为了解决多线程中对同一变量的访问冲突,在普通的同步机制中,是通过对象加锁来实现多个线程对同一变量的安全访问,这时该变量是多个线 程共享的,使用这种同步机制需要很细致的分析出某时是哪个线程在操作该变量。 ThreadLocal 是从另一个角度来解决多线程的并发访问,ThreadLocal 会为每一个线程管理一个和该线程绑定的变量副本,从而隔离了对歌线程的数据,每一个线程都拥有自己的变量副本,因此也没有必要对该变量同步了。 ThreadLocal 并不能代替其它同步机制,两者面向的方向不同。其它同步机制是为了同步多个线程对相同资源的并发访问,是为了对个线程之间进行通信的有效方式,而 ThreadLocal 是隔离多个线程的数据共享,从根本上就不存在多个线程的共享资源。所以,如果你需要进行多个线程之间的通信,则使用同步机制,如果需要隔离多个线程之间的 共享冲突,可以使用 ThreadLocal ,这将极大简化代码量,并且美观易读。
ThreadLocal 内部机制
在 ThreadLocal 中,有一个Map集合,其中线程的对象引用作为键(key),而值(value)存放的是你丢进去的对象。对于同一个线程返回的是同一个 value,不同的线程返回的是不同的 value。这是通过 ThreadLocal 的 set()、get() 方法实现的。在某一个线程结束前,应当清除存放在 ThreadLocal 中的对象,否则会导致服务器存放过多的垃圾。清除对象的方法是,在该线程下,调用 ThreadLocal 对象的 remove() 方法。
ThreadLocal 常见方法
- void set(Object value) 设置当前线程的局部变量的值
- Object get() 返回当前线程的局部变量的值
- void remove() 将当前线程的局部变量的值删除,目的是为了减少内存占用。 当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。
- protected Object intialValue 返回该线程的局部变量的初始值。该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用 get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。
举例说明 ThreadLocal 的使用方法
编写代码,实现5个线程对同一对象的访问,并且保证在一个线程内获取的对象是同一个对象。
运行结果为:
Thread-0A:21
Thread-1A:44
Thread-4A:57
Thread-3A:55
Thread-2A:23
Thread-3B:55
Thread-4B:57
Thread-1B:44
Thread-0B:21
Thread-2B:23
由此反应出 ThreadLocal 保证了同一线程内的变量共享。