`
sole
  • 浏览: 141530 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java局部线程变量---ThreadLocal

阅读更多
  • ThreadLocal是什么

早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。

ThreadLocal很容易让人望文生义,想当然地认为是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它命名为ThreadLocalVariable更容易让人理解一些。

当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思。

线程局部变量并不是Java的新发明,很多语言(如IBM IBM XL FORTRAN)在语法层面就提供线程局部变量。在Java中没有提供在语言级支持,而是变相地通过ThreadLocal的类提供支持。

所以,在Java中编写线程局部变量的代码相对来说要笨拙一些,因此造成线程局部变量没有在Java开发者中得到很好的普及。

  • 官方Java 5.0文档提供的说明
public class ThreadLocal<T>
extends Object
 

该类提供了线程局部变量。这些变量不同于它们的普通对应物,因为访问一个变量(通过其 getset 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的私有静态字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。

例如,在下面的类中,私有静态 ThreadLocal 实例(serialNum)为调用该类的静态 SerialNum.get() 方法的每个线程维护了一个“序列号”,该方法将返回当前线程的序列号。(线程的序列号是在第一次调用 SerialNum.get() 时分配的,并在后续调用中不会更改。)

public class SerialNum ...{
     
// The next serial number to be assigned
     private static int nextSerialNum = 0;

     
private static ThreadLocal serialNum = new ThreadLocal() ...{
         
protected synchronized Object initialValue() ...{
             
return new Integer(nextSerialNum++);
         }

     }
;

     
public static int get() ...{
         
return ((Integer) (serialNum.get())).intValue();
     }

 }

 

每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的;在线程消失之后,其线程局部实例的所有副本都会被垃圾回收(除非存在对这些副本的其他引用)。 

 

 

从以下版本开始:
1.2
  • ThreadLocal的接口方法

     

    initialValue

    protected T initialValue()
    返回此线程局部变量的当前线程的初始值。最多在每次访问线程来获得每个线程局部变量时调用此方法一次,即线程第一次使用 get() 方法访问变量的时候。如果线程先于 get 方法调用 set(T) 方法,则不会在线程中再调用 initialValue 方法。

    该实现只返回 null;如果程序员希望将线程局部变量初始化为 null 以外的某个值,则必须为 ThreadLocal 创建子类,并重写此方法。通常,将使用匿名内部类。initialValue 的典型实现将调用一个适当的构造方法,并返回新构造的对象。

     

    返回:
    返回此线程局部变量的初始值

    <!---->

    get

    public T get()
    返回此线程局部变量的当前线程副本中的值。如果这是线程第一次调用该方法,则创建并初始化此副本。

     

    返回:
    此线程局部变量的当前线程的值

    <!----><!---->

    set

    public void set(T value)
    将此线程局部变量的当前线程副本中的值设置为指定值。许多应用程序不需要这项功能,它们只依赖于 initialValue() 方法来设置线程局部变量的值。

     

    参数:
    value - 存储在此线程局部变量的当前线程副本中的值。

    <!---->

    remove

    public void remove()
    移除此线程局部变量的值。这可能有助于减少线程局部变量的存储需求。如果再次访问此线程局部变量,那么在默认情况下它将拥有其 initialValue

     

    从以下版本开始:
    1.5

 

  • Thread同步机制的比较

ThreadLocal和线程同步机制相比有什么优势呢?ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。

在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。

而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。

概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

分享到:
评论

相关推荐

    WHUT-java多线程实验-第二周-异常处理.zip

    1. **线程局部变量(ThreadLocal)**:线程局部变量为每个线程都创建了独立的副本,这样在处理异常时,不会互相影响。 2. **线程间的通信(Synchronized、wait()、notify()、notifyAll())**:在同步控制下,确保了...

    java事务 - threadlocal

    Java事务和ThreadLocal是两种在Java编程中至关重要的概念,它们分别用于处理多线程环境下的数据一致性问题和提供线程局部变量。 首先,我们来深入理解Java事务。在数据库操作中,事务是一系列操作的集合,这些操作...

    多线程线程变量赋值

    线程变量,也称为线程局部变量,是一种特殊类型的变量,它为每个线程维护独立的副本。这意味着,即使多个线程访问同一个线程局部变量,它们各自看到的都是自己独有的副本,不会相互影响。这种特性在多线程环境中非常...

    ThreadLocal 线程本地变量 及 源码分析.rar_开发_设计

    ThreadLocal是Java编程语言中的一个类,用于在多线程环境下提供线程局部变量。它为每个线程创建了一个独立的变量副本,每个线程只能访问自己的副本,不会影响其他线程。这种机制有助于实现线程安全,尤其在需要线程...

    Java多线程编程总结

    - 线程栈中的局部变量只在线程中可见,不会与其他线程共享。 2. **线程的变量** - `ThreadLocal` 类提供了一种机制,允许线程拥有独立的副本变量。 - 通过 `ThreadLocal` 可以确保线程之间的数据隔离,避免数据...

    局部变量线程安全测试

    测试可能包括对局部变量的读写操作,以及涉及到同步机制如synchronized关键字,volatile修饰符,或者是使用ThreadLocal等技术来确保线程安全。 在标签中,“局部变量”、“线程”、“安全”、“测试”和“源码”是...

    java多线程的讲解和实战

    10. **线程局部变量(ThreadLocal)**:为每个线程提供独立的变量副本,确保线程间的隔离,避免了共享状态带来的问题。 实战部分将通过具体的代码示例展示如何创建和管理线程,如何实现线程同步,以及如何利用...

    Java多线程 之 临界区、ThreadLocal.docx

    ThreadLocal是一种线程局部变量,它为每个线程都创建了一个独立的变量副本,从而避免了线程间的资源共享,减少了并发问题。每个线程都有自己的ThreadLocal变量,它们之间互不影响。ThreadLocal通常用于存储线程私有...

    Java资料-详解ThreadLocal

    `ThreadLocal`的全称是`java.lang.ThreadLocal`,它并不是一个线程,而是一个线程局部变量的容器。`ThreadLocal`的工作原理是为每个线程创建一个单独的实例副本,这些副本存储在一个与线程相关的映射表中。当线程...

    Java多线程运算集合

    - **线程变量**: - Java提供了一种特殊类型的变量——`ThreadLocal` 变量,它可以为每个线程提供一个独立的变量副本,使得每个线程都可以独立地改变自己的副本,而不会影响其他线程。 #### 四、Java线程状态的...

    java中ThreadLocal详解

    1. **获取线程局部变量**:当线程试图获取线程局部变量的值时,首先会通过`Thread.currentThread()`获取当前线程。然后,通过当前线程获取对应的`ThreadLocalMap`实例,并基于`ThreadLocal`对象作为键查找对应的值。...

    java多线程

    - 掌握线程局部变量(ThreadLocal)的使用,理解其在并发环境下的优势。 7. Java并发API的演进 - 理解Java 5之后引入的并发API,如java.util.concurrent包; - 掌握Fork/Join框架的设计和使用,以及其对并发性能...

    Java多线程与线程安全实践-基于Http协议的断点续传

    4. **线程局部变量**:`ThreadLocal`类提供了一种线程内的局部变量,每个线程都拥有自己的一份独立副本,互不影响。 5. **volatile关键字**:它用于标记一个变量,使得多个线程可以共享这个变量,且能保证可见性和...

    java核心知识点学习----多线程间的数据共享和对象独立,ThreadLocal详解.pdf

    ThreadLocal是Java提供的一种线程局部变量,每个线程都拥有自己独立的ThreadLocal副本,互不影响。在上述代码中,创建了一个ThreadLocal实例,然后在线程的run()方法中设置值,每个线程设置的数据只对自己可见,...

    java中ThreadLocal类的使用

    Java中的`ThreadLocal`类是一个非常实用的工具,它提供了线程局部变量的功能。线程局部变量意味着每个线程都拥有自己独立的变量副本,互不干扰,这在多线程编程中尤其有用,可以避免数据共享带来的同步问题。下面...

    java 多线程编程实战指南(核心 + 设计模式 完整版)

    - **线程局部变量**:`ThreadLocal`用于存储每个线程的私有数据,避免数据冲突。 - **异常处理**:确保线程中的异常不会无声无息地消失,以免影响其他线程。 7. **性能调优** - **线程优先级**:了解线程优先级...

    Java中ThreadLocal的设计与使用

    Java中的ThreadLocal是一个非常重要的工具类,它在多线程编程中扮演着独特角色,用于为每个线程提供独立的变量副本。理解ThreadLocal的工作原理和使用方法对于编写高效、安全的多线程程序至关重要。 ### ...

    Java多线程-线程安全问题练习题

    4. **线程局部变量**:`ThreadLocal`类,为每个线程提供独立的变量副本,避免了共享状态的问题。 5. **并发工具类**:如`CountDownLatch`, `CyclicBarrier`, `Semaphore`等,帮助开发者更好地管理线程间的协作。 ...

    java线程 线程学习资料 java线程教程

    - `ThreadLocal`类提供线程局部变量,避免共享数据带来的问题。 #### 七、高级主题 - **线程池**: - 使用`ExecutorService`接口来管理和复用一组工作线程。 - 减少创建和销毁线程的开销。 - **并发集合与工具类*...

    java多线程面试题59题集合

    9. **线程局部变量** - ThreadLocal:每个线程都有自己独立的副本,不会互相影响,用于存储线程相关的数据。 以上只是Java多线程面试中可能会遇到的一部分问题,实际的59题集合可能涵盖更多细节和深度,包括线程...

Global site tag (gtag.js) - Google Analytics