`
wake.up
  • 浏览: 13850 次
社区版块
存档分类
最新评论

java -ThreadLocal

    博客分类:
  • java
阅读更多

ThreadLocal

什么是ThreadLocal?

顾名思义它是local variable(线程局部变量)。它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。

使用场景

  1. To keep state with a thread (user-id, transaction-id, logging-id)
  2. To cache objects which you need frequently

ThreadLocal类

它 主要由四个方法组成initialValue(),get(),set(T),remove(),其中值得注意的是initialValue(),该方法 是一个protected的方法,显然是为了子类重写而特意实现的。该方法返回当前线程在该线程局部变量的初始值,这个方法是一个延迟调用方法,在一个线 程第1次调用get()或者set(Object)时才执行,并且仅执行1次。ThreadLocal中的确实实现直接返回一个null:

ThreadLocal的原理

ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。比如下面的示例实现:

public class ThreadLocal
{
 private Map values = Collections.synchronizedMap(new HashMap());
 public Object get()
 {
  Thread curThread = Thread.currentThread();
  Object o = values.get(curThread);
  if (o == null && !values.containsKey(curThread))
  {
   o = initialValue();
   values.put(curThread, o);
  }
  return o;
 }

 public void set(Object newValue)
 {
  values.put(Thread.currentThread(), newValue);
 }

 public Object initialValue()
 {
  return null;
 }
}

ThreadLocal 的使用

使用方法一:

Hibernate的文档时看到了关于使ThreadLocal管理多线程访问的部分。具体代码如下

1.   public static final ThreadLocal session = new ThreadLocal();
2.   public static Session currentSession() {
3.       Session s = (Session)session.get();
4.       //open a new session,if this session has none
5.   if(s == null){
6.       s = sessionFactory.openSession();
7.       session.set(s);
8.   }
       return s;
9. }

我们逐行分析
1。 初始化一个ThreadLocal对象,ThreadLocal有三个成员方法 get()、set()、initialvalue()。
     如果不初始化initialvalue,则initialvalue返回null。
3。 session的get根据当前线程返回其对应的线程内部变量,也就是我们需要的net.sf.hibernate.Session(相当于对应每个数据 库连接).多线程情况下共享数据库链接是不安全的。ThreadLocal保证了每个线程都有自己的s(数据库连接)。
5。如果是该线程初次访问,自然,s(数据库连接)会是null,接着创建一个Session,具体就是行6。
6。创建一个数据库连接实例 s
7。保存该数据库连接s到ThreadLocal中。
8。如果当前线程已经访问过数据库了,则从session中get()就可以获取该线程上次获取过的连接实例。

使用方法二

当要给线程初始化一个特殊值时,需要自己实现ThreadLocal的子类并重写该方法,通常使用一个内部匿名类对ThreadLocal进行子类化,EasyDBO中创建jdbc连接上下文就是这样做的:

public class JDBCContext{
private static Logger logger = Logger.getLogger(JDBCContext.class);
private DataSource ds;
protected Connection connection;
private boolean isValid = true;
private static ThreadLocal jdbcContext;

private JDBCContext(DataSource ds){
   this.ds = ds;
   createConnection();  
}
public static JDBCContext getJdbcContext(javax.sql.DataSource ds)
{  
   if(jdbcContext==null)jdbcContext=new JDBCContextThreadLocal(ds);
   JDBCContext context = (JDBCContext) jdbcContext.get();
   if (context == null) {
    context = new JDBCContext(ds);
   }
   return context;
}

private static class JDBCContextThreadLocal extends ThreadLocal {
   public javax.sql.DataSource ds;
   public JDBCContextThreadLocal(javax.sql.DataSource ds)
   {
    this.ds=ds;
   }
   protected synchronized Object initialValue() {
    return new JDBCContext(ds);
   }
}
}

 

分享到:
评论

相关推荐

    java事务 - threadlocal

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

    java-threadlocal-profiler:从 code.google.compjava-threadlocal-profiler 自动导出

    Java 线程本地分析器。 用于 Java 应用程序分析的小库。 收集同一伞下的所有性能指标,可以一起打印出来。 最好与一些日志框架一起使用。 核心没有任何依赖关系,因此可以位于类加载器层次结构的顶部。 支持 Spring...

    Quartz-ThreadLocal.rar

    ThreadLocal 是 Java 中的一个重要工具类,用于在多线程环境中为每个线程维护独立的变量副本。这个压缩包 "Quartz-ThreadLocal.rar" 内含的学习资源很可能是关于如何在 Quartz 调度器中结合使用 ThreadLocal 的示例...

    Spring事务处理-ThreadLocal的使用

    ThreadLocal是Java提供的一种线程局部变量,每个线程都有自己的ThreadLocal实例,并且可以独立地修改自己的副本,而不会影响其他线程。在Spring事务管理中,ThreadLocal被用来存储当前线程的事务信息,例如事务隔离...

    java8-threadlocal

    Java 8 中的 ThreadLocal 是一个非常重要的工具类,它为每个线程提供了一个独立的变量副本,使得每个线程可以独立地改变自己的副本,而不会影响其他线程所对应的副本。这个特性在多线程编程中被广泛用于管理线程相关...

    Java资料-详解ThreadLocal

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

    java中ThreadLocal详解

    ### Java中ThreadLocal详解 #### 一、ThreadLocal概述 在Java多线程编程中,`ThreadLocal`是一个非常重要的工具类,它提供了一种在每个线程内部存储线程私有实例的方法。通常情况下,当多个线程共享某个变量时,...

    Java中ThreadLocal的设计与使用

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

    53.线程间的通信-join方法-ThreadLocal类.mp4

    在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。

    Java-concurrency-master.zip

    9. **线程局部变量**:`ThreadLocal`类为每个线程都提供了一个独立的变量副本,确保了线程间的隔离性。 10. **死锁、活锁与饥饿**:并发编程中可能出现的三种问题,理解并避免这些情况是保证程序稳定运行的关键。 ...

    java ThreadLocal多线程专属的变量源码

    java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多...

    Java-Interview-超全集合github上评分最高的jiva面试题

    - **线程**:创建线程的方式,理解线程的状态转换,掌握ThreadLocal的使用。 - **同步机制**:synchronized关键字、Lock接口(ReentrantLock、Condition)的使用,以及死锁的概念。 - **并发容器**:如...

    java-java-lang包.pdf

    - ThreadLocal:用于提供线程内部的局部变量。 6. 实用工具类: - String:表示字符串,提供了丰富的字符串操作方法。 - StringBuffer:表示字符序列,与String不同,StringBuffer是可变的,适合频繁修改的场景...

    java 简单的ThreadLocal示例

    Java中的ThreadLocal是一个非常重要的工具类,它在多线程编程中扮演着独特角色,尤其在处理线程间数据隔离和共享时。ThreadLocal不是线程本身,而是为每个线程提供一个独立的变量副本,使得每个线程都可以独立地改变...

    java中ThreadLocal类的使用

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

    JAVA并发-自问自答学ThreadLocal.pdf

    【ThreadLocal】是Java编程语言中用于处理线程局部变量的一个工具类,它提供了一种在多线程环境中实现线程安全的局部变量的方式。在Java的并发编程中,ThreadLocal是一个非常重要的概念,它可以帮助我们创建独立于...

    ikm-java-material-005.pdf

    - 使用ThreadLocal变量,为每个线程提供独立的变量副本,从而实现线程安全。 - 使用final类或者字段,确保类或者字段不能被继承或修改。 - 通过@Multithread注解来指定一个类是线程安全的,但这是第三方提供的,并不...

    ThreadLocal应用示例及理解

    **线程局部变量(ThreadLocal)是Java编程中一个非常重要的工具类,它在多线程环境下提供了线程安全的数据存储。ThreadLocal并不是一个变量,而是一个类,它为每个线程都创建了一个独立的变量副本,使得每个线程都...

    Java ThreadLocal详解_动力节点Java学院整理

    Java ThreadLocal详解 ThreadLocal是Java中的一种机制,可以将变量与线程关联起来,使得每个线程都可以拥有自己的变量副本。 ThreadLocal的出现是为了解决多线程编程中的线程安全问题。 从本质上说,ThreadLocal是...

    使用Java ThreadLocal.docx

    Java中的ThreadLocal是一个非常有用的工具类,它提供了一种线程局部变量的机制。线程局部变量(ThreadLocal)的特点是每个线程都有其独立的副本,这些副本之间互不干扰,即使它们共享同一个ThreadLocal实例。这使得...

Global site tag (gtag.js) - Google Analytics