美文网首页JAVA
ThreadLocal 浅析

ThreadLocal 浅析

作者: 清风徐来水波不清 | 来源:发表于2017-12-24 19:52 被阅读5次

ThreadLocal是什么?

早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。
java.lang.ThreadLocal提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。
每个线程都保持对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的;在线程消失之后,其线程局部实例的所有副本都会被GC回收(除非存在对这些副本的其他引用)。

ThreadLocal接口方法

  • ThreadLocal对外提供了四个方法:
    • void set(T value) 设置当前局部变量的值
   public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }
  • product T initialValue() 返回该线程局部变量的初始值,该方法是一个protected的方法,方法内部并没有具体实现代码,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。但是如果在调用 get() 后又调用了 remove(),则可能再次调用此方法。
 protected T initialValue() {
       return null;
   }
  • public T get() 该方法返回当前线程所对应的线程局部变量
       Thread t = Thread.currentThread();
       ThreadLocalMap map = getMap(t);
       if (map != null) {
           ThreadLocalMap.Entry e = map.getEntry(this);
           if (e != null)
               return (T)e.value;
       }
       return setInitialValue();
   }
  • public void remove() 将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。其实在线程结束后对应的线程变量会自动被GC,主动调用这个方法目的是尽早回收,释放内存.
  public void remove() {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if (m != null)
             m.remove(this);
     }

源码浅析

也许我们分析JDK中的源码有些难以理解,我们可以将ThreadLocal类简化一下,简化后的代码如下

class MyThreadLocal<T>{
private Map<Thread,T> map = new HashMap<Thread,T>();
     protected T initialValue() {
        return null;
    }
  
  public void set(T value) {
        map.put(Thread.currentThread(), value);
    }
    
    public void remove() {
        map.remove(Thread.currentThread());
    }
    
    public T get() {
        return map.get(Thread.currentThread());
    }
}

其实在ThreadLocal内部是维护了一个Map来保存数据的,虽然使用的时候获取的是value值,但是其每一个value对应的key都是当前线程,因此相当于将变量给每一个线程复制了一份,各个线程对数据的操作不会互相影响.

实用案例

我们在对数据库进行操作的时候有时候为了数据安全必须加事务操作,但是一般事务管理在Service层,而数据操作在DAO层,一般的做法就是在Service层建立连接然后传参的形式传递给DAO层,这无疑增加了程序的侵入性,其实在Spring的事务管理底层就使用了ThreadLocal来解决这种情况,我们也可以模拟使用ThreadLocal编写一个带有事务操作工具类.

public class JdbcUtils {
    private static DataSource dataSource = new ComboPooledDataSource();
    private static ThreadLocal<Connection> tl  = new ThreadLocal<Connection>();
  //获取数据源
    public static DataSource getDataSource() {
        return dataSource;
    }
  //获取连接
    public static Connection getConnection() throws SQLException {
        Connection con = tl.get(); 
        if(con == null) {
            return dataSource.getConnection();
        }
        return con;
    }
    //开始事务
    public static void beginTranscation() throws SQLException {
        Connection con = tl.get(); 
        if(con != null ) {
            throw new SQLException("事务已经开启,在没有结束当前事务时,不能再开启事务!");
        }
        con = dataSource.getConnection(); 
        con.setAutoCommit(false); 
        tl.set(con); 
    }
    //提交事务
    public static void commitTransaction() throws SQLException {
        Connection con = tl.get(); 
        if(con == null ) {
            throw new SQLException("当前没有事务,所以不能提交事务!");
        }
        con.commit(); 
        con.close(); 
        tl.remove(); 
    }
    // 回滚事务
    public static void rollbackTransaction() throws SQLException {
        Connection con = tl.get();
        if(con == null) {
            throw new SQLException("当前没有事务,所以不能回滚事务!");
        }
        con.rollback();
        con.close();
        tl.remove();
    }
}

相关文章

  • ThreadLocal浅析

    一、ThreadLocal简介及误区 ThreadLocal一般称为线程本地变量,它是一种特殊的线程绑定机制,将变...

  • ThreadLocal 浅析

    ThreadLocal是什么? 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,Thr...

  • ThreadLocal浅析

    什么是ThreadLocal: ThreadLocal 提供了线程本地的实例。 它与普通变量的区别在于,每个使用该...

  • ThreadLocal浅析

    ThreadLocal用来存储线程隔离的数据。 Thread类中有一个ThreadLocalMap成员变量thre...

  • 浅析 ThreadLocal (Android)

    一. ThreadLocal 是什么 ThreadLocal用于实现在不同的线程中存储线程私有数据的类,通过它可以...

  • ThreadLocal 源码浅析

    首先,什么是ThreadLocal? 看一下源码上的定义: 英语比较差劲,凑合翻译一下,大意是threadLoac...

  • ThreadLocal源码浅析

    本章内容概要 ThreadLocal用法demo ThreadLocal内部类ThreadLocalMap简述 T...

  • JAVA-ThreadLocal浅析

    概述 ThreadLocal如果单纯从名字上来看像是“本地线程"这么个意思,只能说这个名字起的确实不太好,很容易让...

  • Android笔记——ThreadLocal原理浅析

    复习和回顾Android知识,梳理笔记 ThreadLocal简介 ThreadLocal一般在开发中不是很常见,...

  • ThreadLocal

    ThreadLocal 简介ThreadLocal 使用ThreadLocal 原理InheritableThre...

网友评论

    本文标题:ThreadLocal 浅析

    本文链接:https://www.haomeiwen.com/subject/fibhgxtx.html