`
zys0523
  • 浏览: 31716 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

跨线程使用ThreadLocal

 
阅读更多

最近围观@田麦大牛的代码,看到ThreadLocal还能这么玩,故此记录一下

ThreadLocal概念:http://blog.csdn.net/qjyong/article/details/2158097

可以明显看到ThreadLocal中的值是和线程本身绑定的,那么如果我在A线程中使用了ThreadLocal,set了一个变量,然后在B线程如何取出来呢。

往ThreadLocal中set变量时,可以debug这个类,发现类中除了一串hashCode外什么都没有,那么这个值究竟放在哪里呢?

threadLocalHashCode = -387276957

 看一下ThreadLocal的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);
    }

可以看到ThreadLocal的变量全部是存储在Thread的

    /* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
    ThreadLocal.ThreadLocalMap threadLocals = null; 

  中,由于ThreadLocalMap是不可见的,所以只能通过反射的方式去调用。

到此为止,ThreadLocal就已经与线程并非完全相关了,你大可以对ThreadLocalMap进行copy,在采用事件回调等机制不同线程的情况下也可以run的很愉快了。完整代码如下:

public abstract class Task implements Runnable {
    Object threadLocal;
    public Task(Object threadLocalMap){
        this.threadLocal =threadLocalMap;
    }
    public final void run(){
        BeanUtils.forceSetProperties(Thread.currentThread(), threadLocal, "threadLocals");
        realRun();
    }

    protected abstract void realRun();
}
 

例子:

public class ThreadLocalTest {
    private static final ThreadLocal<String> tl = new ThreadLocal<String>();

    static class MyTask extends Task{
        public MyTask(Object threadLocal){
            super(threadLocal);
        }
        @Override
        public void realRun() {
            System.out.println("I'm Thread:"+Thread.currentThread().getName()+", value is:"+tl.get());
          }
    }

    public static void main(String[] args) {
        tl.set("hello world");
        Object threadLocals = BeanUtils.forceGetProperties(Thread.currentThread(),"threadLocals");
        Executors.newSingleThreadExecutor().submit(new MyTask(threadLocals));
        System.out.println("I'm Thread:"+Thread.currentThread().getName()+", value is:"+tl.get());
    }

}

BeanUtils:

public static Object forceGetProperties(Object object, String fieldName){
        try {
            Field field = object.getClass().getDeclaredField(fieldName);
            if (!field.isAccessible()){
                field.setAccessible(true);
            }
            return field.get(object);
        } catch (Exception e) {
            //ignore
            return null;
        }
    }

    public static void forceSetProperties(Object target,Object arg, String fieldName){
        try {
            Field field = target.getClass().getDeclaredField(fieldName);
            if (!field.isAccessible()){
                field.setAccessible(true);
            }
            field.set(target,arg);
        } catch (Exception e) {
            //ignore
        }
    } 

 

运行结果:

I'm Thread:main, value is:hello world

I'm Thread:pool-1-thread-1, value is:hello world

分享到:
评论

相关推荐

    使用ThreadLocal管理“session”数据

    - 局限:ThreadLocal并非万能解决方案,它不能解决跨线程的数据共享需求。此外,如果不及时清理ThreadLocal,可能导致内存泄漏。 5. **源码解析** 要深入理解ThreadLocal的工作原理,需要查看其源码。ThreadLocal...

    ThreadLocal

    - 不适用于跨线程通信:ThreadLocal只保证同一线程内的数据隔离,不同线程间无法共享ThreadLocal变量。 - 不是线程安全的:尽管ThreadLocal提供了线程隔离,但它本身并不保证线程安全性,如果在`set`和`get`操作之间...

    Hystrix跨线程传递数据解决方案:HystrixRequestContext.docx

    通过 `HystrixRequestContext` 和相关的 API,Hystrix 能够有效地管理跨线程的数据传递,使得开发人员能够在使用线程池隔离模式时轻松地处理上下文数据。这种机制不仅提高了代码的可维护性和可读性,而且也增强了...

    跨线程提交数据

    在多线程编程中,"跨线程提交数据"是一个重要的概念,特别是在并发处理和优化应用程序性能时。本文将深入探讨这一主题,旨在为初学者提供一个全面的理解。 首先,我们要明白什么是线程。线程是操作系统分配CPU时间...

    ThreadLocal简单Demo

    - 虽然`ThreadLocal`能提供线程隔离,但不适用于跨线程的共享数据。 - `ThreadLocalMap`的扩容策略和哈希冲突处理不同于标准的`HashMap`,理解其内部机制有助于避免潜在的问题。 以上就是关于`ThreadLocal`及其内部...

    ThreadLocal_ThreadLocal源码分析_

    因此,ThreadLocal不适合用于存储跨线程或者线程池中的共享数据。 **使用ThreadLocal的最佳实践** 1. **初始化和清理**:使用ThreadLocal时,应该在首次使用时进行初始化,并在不再需要时进行清理,避免内存泄漏。...

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

    - **线程隔离性**:ThreadLocal只在创建它的线程内有效,无法跨线程共享数据。 - **难以调试**:由于ThreadLocal的隐式性,有时可能会导致难以发现的问题,特别是当线程池中的线程复用时。 ### 4. 使用注意事项 - ...

    ThreadLocal垮线程池传递数据解决方案.docx

    这时,ThreadLocal 的局限性就暴露出来了,即它不能解决跨线程池之间的数据传递问题。 为了解决这个问题,TransmittableThreadLocal 诞生了。TransmittableThreadLocal 是一种专门为线程池设计的ThreadLocal解决...

    ThreadLocal测试工程

    7. **局限性**:ThreadLocal不适合跨线程通信,如果需要在多个线程间共享数据,应该考虑使用其他机制,如线程安全的数据结构或通过消息传递。 在"ThreadLocal测试工程"中,通过`ThreadLocalTest`这个类,我们可以...

    Python之ThreadLocal共4页.pdf.zip

    对于需要跨线程共享的数据,应该考虑使用锁或其他同步机制。ThreadLocal主要是为了隔离线程数据,而不是共享。 在实际开发中,ThreadLocal常常与装饰器结合使用,以便更方便地在函数级别控制线程局部变量。通过定义...

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

    - 不要将ThreadLocal用作全局变量,因为它们只在创建它们的线程内有效,无法跨线程共享。 - 谨慎处理生命周期管理,尤其是在静态变量中使用ThreadLocal,确保在不再需要时正确清理,防止内存泄漏。 6. **应用场景...

    ThreadLocal那点事儿编程开发技术共6页.pdf

    5. **线程局部变量的局限性**:ThreadLocal并不是万能的解决方案,它不能解决所有线程间通信的问题,特别是对于需要跨线程共享数据的情况,ThreadLocal就无能为力了。此外,过度依赖ThreadLocal可能导致程序设计过于...

    Java多线程编程之ThreadLocal线程范围内的共享变量

    4. **缓存**:ThreadLocal可以用于实现线程级别的缓存,每个线程有自己的缓存,提高局部访问效率,减少跨线程同步的开销。 **ThreadLocal的使用实例:** 以下是一个简单的ThreadLocal使用示例: ```java public ...

    Java资料-详解ThreadLocal

    在某些情况下,如数据需要跨线程共享,`ThreadLocal`就无能为力了。此外,如果不正确地管理`ThreadLocal`,可能会导致内存泄漏。当线程结束时,它所关联的`ThreadLocal`值并不会自动清除,因此如果主线程或守护线程...

    18 线程作用域内共享变量—深入解析ThreadLocal.pdf

    2. **跨层传递参数**:在分层架构中,从高层到低层传递参数时,可以使用`ThreadLocal`避免参数的逐层传递。特别是当某个参数在较深层级的方法中被需要时,直接从`ThreadLocal`中获取比通过参数传递更为便捷。 **...

    正确理解ThreadLocal

    3. **线程局部性**:ThreadLocal的变量只存在于当前线程,跨线程无法访问,不适合需要跨线程共享数据的场景。 总结来说,ThreadLocal是Java中用于解决线程间数据隔离问题的有效工具,但需要谨慎使用,尤其是在处理...

    java的ThreadLocal[整理].pdf

    如果线程结束,ThreadLocalMap及其所有的Entry都会被销毁,因此ThreadLocal不适用于跨线程持久化的数据存储。此外,如果线程长时间运行,而ThreadLocal未被清除,可能会导致内存泄漏,因为ThreadLocalMap不会自动...

Global site tag (gtag.js) - Google Analytics