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

Java ThreadLocal 应用

    博客分类:
  • Java
阅读更多
一、需求介绍
由于项目需要在同一进程不同方法内获取到上下文内容,而在同一线程父方法可以获取到上下文内容,子方法由不同的项目组提供和开发,然后以jar包的方式打包,这时候问题就出现了,父方法的上下文内容如何可以提供给子方法,并在子方法中获取到对应线程的上下文内容?

注:每个线程的上下文内容是不同的,父类只提供集成容器,具体方法的实现由不同的项目组和部门编写

二、解决思路
应用Java 提供的ThreadLocal

首先查看下TheadLocal提供的方法
T get()
          返回此线程局部变量的当前线程副本中的值。
protected  T initialValue()
          返回此线程局部变量的当前线程的初始值。
void remove()
          移除此线程局部变量的值。
void set(T value)
          将此线程局部变量的当前线程副本中的值设置为指定值。


2.1、get 方法:
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();
}

说明:
1、首先获取当前线程
2、获取当前线程的ThreadLocalMap即threadLocals
getMap(Thread t)源码为:
ThreadLocalMap getMap(Thread t) {
    return t.threadLocals;
}
3、如果当前线程存在threadLocals则根据当前的ThreadLocal获取threadLocals的值.(threadLocals其实就是一Map)
4、如果当前线程的ThreadLocalMap为null,则执行方法setInitialValue()

可以看的出是获取Thread的threadLocals
Thread中源码为如下:
ThreadLocal.ThreadLocalMap threadLocals = null;

2.2、set 方法
public void set(T value) {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null)
        map.set(this, value);
    else
        createMap(t, value);
}
源码说明:
1、首先获取当前线程
2、获取当前线程ThreadLocalMap
3、如果ThreadLocalMap不为null set(ThreadLocal,value)
4、如果为null createMap(Thread,value);

备注:这里可以看出不为null时,set的内容为key:ThreadLocal,value:value,也就是说每个线程都有一个ThreadLocalMap这个map内存放得内容为ThreadLocal,value

接下来在看下createMap源码
void createMap(Thread t, T firstValue) {
    t.threadLocals = new ThreadLocalMap(this, firstValue);
}

备注:该方法为当前线程的内部变量threadLocals进行了赋值操作,而ThreadLocalMap为ThreadLocal的内部类。new ThreadLocalMap(this, firstValue) 内部进行的操作也是为当前线程的threadLocals变量进行了set操作,key为当前的ThreadLocal,value为传入的firstValue

2.3、setInitialValue方法

private T setInitialValue() {
    T value = initialValue();
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null)
         map.set(this, value);
    else
         createMap(t, value);
    return value;
}

该方法返回null,并会创建当前线程的threadLocals

综上:应用ThreadLocal在线程中进行上下文同步时,要保持一致的ThreadLocal。当多线程应用线程池时,要保证线程池中相同的线程每次拿到得ThreadLocal要不相同,否则会出现问题。


回到问题的开始,解决该问题的方案为
1、创建一个单例类(ex:ThreadLocalTest)保证线程上下文拿到得ThreadLocal都一致
2、父类提供给子类可以获取单例类ThreadLocalTest的方法。(要是子类分别由不同的部门、项目组以jar的方式提供时,负责父类服务的可以给项目组提供一个通用的jar文件)
3、在调用父类多线程入口时获取ThreadLocalTest单例,set(上下文内容)
4、子类在方法内获取ThreadLocalTest单例调用get()方法获取当前线程的value即为上下文内容
5、父类调用子方法后执行ThreadLocalTest.remove()操作

public class ThreadLocalTest<T> {
    private static ThreadLocal local = new ThreadLocal();
    private static ThreadLocalTest threadlocaltest = null;

    public synchronized ThreadLocalTest getInitialize(){
        if(threadlocaltest == null){
            threadlocaltest = new ThreadLocalTest<T>();
        }
        return threadlocaltest;
    }

    public T get(){
        return (T) local.get();
    }

    public void set(T t){
        local.set(t);
    }

    public void remove(){
        local.remove();
    }
}



后记:
很多人问我,在父类中既然可以获取到上下文那直接传给子类方法就行了啊。注意前提说的是父类只负责提供一个容器,具体的实现由不同的部门和项目组编写
分享到:
评论

相关推荐

    ThreadLocal应用示例及理解

    以上就是关于ThreadLocal的基本概念、使用方法、生命周期管理和实际应用示例的详细解释。了解并熟练掌握ThreadLocal可以帮助我们编写出更高效、更安全的多线程代码。在Java并发编程中,ThreadLocal是一个不可或缺的...

    java 简单的ThreadLocal示例

    **ThreadLocal的应用场景:** 1. **线程安全的上下文:** ThreadLocal常用于保存线程上下文信息,如用户Session、数据库连接、事务ID等,确保这些信息只在当前线程内有效。 2. **避免同步:** 如果多个线程需要...

    Java ThreadLocal类应用实战案例分析

    Java ThreadLocal类应用实战案例分析 Java ThreadLocal类是Java语言中的一种线程局部变量机制,允许每个线程都拥有自己的变量副本,从而避免了多线程之间的变量冲突。在本文中,我们将通过实战案例分析Java ...

    JAVA ThreadLocal类深入

    【JAVA ThreadLocal类深入】 Java中的ThreadLocal类是一种线程绑定机制,用于在多线程环境中为每个线程提供独立的变量副本,避免了线程间的数据共享带来的并发访问问题。ThreadLocal并不是一个线程对象,而是线程...

    java ThreadLocal使用案例详解

    Java ThreadLocal使用案例详解 Java ThreadLocal是Java语言中的一种机制,用于为每个线程提供一个独立的变量副本,以解决多线程环境下共享变量的线程安全问题。在本文中,我们将详细介绍Java ThreadLocal的使用案例...

    java中ThreadLocal类的使用

    2. **请求上下文**:在Web应用中,可以使用`ThreadLocal`保存HttpServletRequest或Session对象,方便在同一个请求处理链路中访问。 3. **线程状态**:记录线程执行过程中的状态,例如事务管理、计数器等。 然而,...

    java 中ThreadLocal 的正确用法

    ThreadLocal 可以应用于各种需要与线程关联状态的场景,例如: * 用户 ID、事务 ID 等信息的存储 * Hibernate 的 Session 管理 * 日志记录的线程关联 * 等等 ThreadLocal 的注意事项 在使用 ThreadLocal 时,我们...

    ThreadLocal原理及在多层架构中的应用

    **线程局部变量(ThreadLocal)是Java编程中一个非常重要的概念,主要用于在多线程环境中为每个线程提供独立的变量副本。ThreadLocal不是一种数据结构,而是一种解决线程间共享数据的方式,它提供了线程安全的局部...

    入研究java.lang.ThreadLocal类.docx

    ### 知识点详解:Java.lang.ThreadLocal 类 #### 一、概述 **ThreadLocal** 并非线程的一种特殊实现形式,而是一种为每个线程提供独立副本的机制,通常被称为“线程局部变量”。这种机制使得每个线程都可以独立...

    ThreadLocal

    ThreadLocal的一个经典应用场景是在数据库连接池中,每个线程都可以有自己的数据库连接,而无需在多个线程间共享,这样可以简化代码并提高性能。另外,它也可以用于HTTP请求上下文,存储请求相关的数据,如用户会话...

    java 中ThreadLocal实例分析

    "Java 中ThreadLocal实例分析" Java 中的 ThreadLocal 实例分析是指在多线程环境下,如何使用 ThreadLocal 来实现线程安全。ThreadLocal 是 Java 中的一种机制,用于在多个线程中实现变量的隔离。 在上面的代码中...

    ThreadLocal原理及在多层架构中的应用.pdf

    在Java中,ThreadLocal被广泛应用于Web中间件、服务端编程和微服务架构中,用以解决多线程环境下的数据隔离问题。 首先,ThreadLocal原理是基于每个线程创建一个私有的数据存储结构(ThreadLocalMap),使得线程...

    Java ThreadLocal 线程安全问题解决方案

    Java中的ThreadLocal是解决线程安全问题的一个重要工具,它提供了一种在多线程环境下为每个线程维护独立变量副本的方法,从而避免了共享状态带来的竞态条件和线程安全问题。 线程安全问题通常由全局变量和静态变量...

    正确理解ThreadLocal.pdf

    `ThreadLocal`是Java平台提供的一种线程局部变量的解决方案,它为每一个使用该变量的线程都提供了独立的变量副本,使得每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。这不同于普通的静态...

    深入浅出的学习Java ThreadLocal

    Java ThreadLocal 是一个非常重要的工具类,它提供了一种在多线程环境下为每个线程维护独立变量副本的机制。这种机制使得各个线程能够拥有自己的变量实例,而不会互相干扰,降低了数据共享的复杂性。 ### 应用场景 ...

    ThreadLocal的用处

    ThreadLocal是Java编程语言中的一个强大工具,它主要用于在多线程环境中为每个线程提供独立的变量副本。这个机制确保了线程之间的数据隔离,避免了共享状态带来的并发问题,提高了程序的安全性和效率。ThreadLocal是...

    彻底理解Java中的ThreadLocal

    彻底理解Java中的ThreadLocal ThreadLocal翻译成中文比较准确的叫法应该是:线程局部变量。使用这个工具类可以很简洁地编写出优美的多线程程序。ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这...

    ThreadLocal 内存泄露的实例分析1

    `ThreadLocal` 是 Java 中用于在单个线程内存储线程局部变量的类,每个线程都有自己的副本,不会互相干扰。`MyThreadLocal` 是 `ThreadLocal` 的子类,用于存储 `MyCounter` 对象。在 `LeakingServlet` 的 `doGet` ...

    ThreadLocal的几种误区

    ThreadLocal是Java编程中一种非常特殊的变量类型,它主要用于在多线程环境下为每个线程提供独立的变量副本,从而避免了线程间的数据共享和冲突。然而,ThreadLocal在理解和使用过程中容易产生一些误区,这里我们将...

Global site tag (gtag.js) - Google Analytics