`

ThreadLocal学习

阅读更多
   什么是ThreadLocal呢,它到底解决了一个什么问题?
    顾名思义它是local variable(线程局部变量)。它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。
    在多线程的编程中我们主要关注的是线程的同步,但是我们好像忽略了在有些情况下,我们并不需要同步,需要的是隔离。
 
   ThreadLocal 提供了一个Map 键是当前线程的Thread 对象,值是传入的对象。这样在线程销毁的时候就会销毁对象,不会造成内存的泄漏。
    ————————让我们结合源代码如何实现————————————
     为一个线程保存一个对象的方法:
     public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

    在这里我们可以看出保存的地方是一个java.lang.ThreadLocal.ThreadLocalMap 而键是但前java.lang.ThreadLocal<T> 对象,那为什么是java.lang.ThreadLocal<T> 对象,而不是java.lang.Thread 对象?假如我们用java.lang.Thread 对象当作键,那么当销毁的时候就不能及时释放资源,因为还有对这个线程的引用。

接下来进入方法 java.lang.ThreadLocal.getMap(Thread) 看下:
      ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }
很简单就是普通的getter ,但是t.threadLocals这个对象是什么,接着来看:
      ThreadLocal.ThreadLocalMap threadLocals = null;
  原来它是java.lang.Thread  中一个静态的内置类java.lang.ThreadLocal.ThreadLocalMap<T>
这就是最终存储的地方,这个类是定制的只适合存放thread local 的值。
   这是存入的方法:
/**
         * Set the value associated with key.
         *
         * @param key the thread local object
         * @param value the value to be set
         */
        private void set(ThreadLocal key, Object value) {

            // We don't use a fast path as with get() because it is at
            // least as common to use set() to create new entries as
            // it is to replace existing ones, in which case, a fast
            // path would fail more often than not.

            Entry[] tab = table;
            int len = tab.length;
            int i = key.threadLocalHashCode & (len-1);

            for (Entry e = tab[i];
		 e != null;
		 e = tab[i = nextIndex(i, len)]) {
                ThreadLocal k = e.get();

                if (k == key) {
                    e.value = value;
                    return;
                }

                if (k == null) {
                    replaceStaleEntry(key, value, i);
                    return;
                }
            }

            tab[i] = new Entry(key, value);
            int sz = ++size;
            if (!cleanSomeSlots(i, sz) && sz >= threshold)
                rehash();
        }

   可以看出它是用一个数组来存放java.lang.ThreadLocal.ThreadLocalMap.Entry 的对象,并且如果已经键存在会更新原来的值。
  
    接下来看一下创建存储的方法:
     void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }
    这个方法创建了一个java.lang.ThreadLocal.ThreadLocalMap 的对象,并把这个对象赋值给当前线程的threadLocals 变量,从而达到每个线程拥有一个自己的备份的目的。
     再来看一下如何取放进去的值:
   
 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();
    }
     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;
    }


   很符合我们常用的方法,getter方法,只不过不用输入键的值,而是自动用当前线程当作键来查找对应的值。


   



    
分享到:
评论

相关推荐

    ThreadLocal详解.md

    学习ThreadLocal,了解其中的原理,以及学习其中的优点!避免坑点!!

    Quartz-ThreadLocal.rar

    这个压缩包 "Quartz-ThreadLocal.rar" 内含的学习资源很可能是关于如何在 Quartz 调度器中结合使用 ThreadLocal 的示例。 Quartz 的核心功能包括: 1. **作业与触发器**:在 Quartz 中,任务被称为“作业”(Job)...

    Java并发编程学习之ThreadLocal源码详析

    Java并发编程学习之ThreadLocal源码详析 ThreadLocal是Java并发编程中的一种机制,用于解决多线程访问共享变量的问题。它可以使每个线程对共享变量的访问都是线程安全的,使得多线程编程变得更加简单。 ...

    threadLocal

    - `HttpClient学习笔记.doc`: 可能包含了关于Apache HttpClient的使用教程,包括如何创建HTTP请求,执行GET和POST操作,以及设置请求头和处理响应等内容。 - `HTTP中Get与Post的区别.doc`: 深入解析HTTP协议中的GET...

    从ThreadLocal的使用到Spring的事务管理

    在IT行业中,线程安全和事务管理是两个非常重要的概念,尤其在多线程环境下的分布式系统中。本文将深入探讨ThreadLocal的使用以及...通过深入学习源码和实际应用,我们可以更好地理解其工作原理,并在实践中灵活运用。

    Spring事务处理-ThreadLocal的使用

    通过深入源码学习,我们可以更好地理解Spring如何在多线程环境中优雅地管理事务,以及如何利用ThreadLocal来优化并发性能。同时,了解数据库连接池的工作原理也有助于我们更好地配置和使用连接池,提升应用程序的...

    threadlocal.rar

    ThreadLocal,全称为`java.lang.ThreadLocal`,是Java中一个非常重要的工具类,它主要用于在多线程环境中提供线程局部变量。...学习并理解ThreadLocal的原理和使用方法对于编写高效、安全的多线程Java程序至关重要。

    Java并发编程中ThreadLocal的原理与应用分析

    通过本文的学习,能够掌握ThreadLocal的基本用法及其内部实现原理,从而正确地使用ThreadLocal以提高程序的性能和稳定性。 其他说明:为了更好地理解ThreadLocal的工作机制,建议实际动手尝试文中提供的实例代码,...

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

    【ThreadLocal那点事儿编程开发技术共6页.pdf】 这篇文档深入探讨了Java中的ThreadLocal类,这是一个在多线程编程中非常关键的工具。...如果你希望深入理解ThreadLocal,这份文档无疑是一个很好的学习资源。

    ThreadLocal测试工程

    ThreadLocal是Java编程语言中的一个线程局部变量类,它为每个线程提供了一个独立的变量副本,使得每个线程可以独立地改变自己的副本,而不会影响其他线程所...这有助于深入学习和掌握Java并发编程中的这一重要工具。

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

    在Java中,有多种方式可以实现线程间的数据共享和对象独立,其中ThreadLocal是常用的工具之一。 在多线程环境下,共享数据通常会引发线程安全问题,比如上述例子中的“张三给李四转钱”场景,如果两个线程同时操作...

    Hibernager_Session_Manager_ThreadLocal

    标题“Hibernage_Session_Manager_ThreadLocal”涉及到的是Hibernate框架中的一种优化策略——使用ThreadLocal管理Session。...理解这些知识点对于深入学习Hibernate和优化Java Web应用的数据库操作至关重要。

    Java单线程ThreadLocal串值问题解决方案

    Java单线程ThreadLocal串值问题解决方案主要介绍了Java单线程ThreadLocal串值问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值。 ThreadLocal简介 ThreadLocal是Java中...

    深入学习java ThreadLocal的源码知识

    ThreadLocal是Java编程中一个非常重要的工具类,它允许我们在多线程环境下为每个线程创建独立的变量副本。在每个线程内部,ThreadLocal变量就像一个私有的局部变量,不同线程之间的副本互不干扰,确保了数据的安全性...

    深入浅出的学习Java ThreadLocal

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

    Java ThreadLocal的设计理念与作用

    主要介绍了Java ThreadLocal的设计理念与作用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    京东一面:说出ThreadLocal的使用场景及使用方式.zip

    计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料 计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料 计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料 计算机技术、IT咨询、人工智能AI理论介绍,...

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

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

    Struts2 学习 2

    本教程“Struts2 学习 2”将深入探讨Struts2的核心概念和技术,通过一系列文档帮助你掌握这个框架的关键要点。 一、ActionContext的理解与应用 在“第九讲 ActionContext.docx”中,你将学习到ActionContext是...

    多线程的学习资料(对初学者特别有用)!

    为了实现线程安全,我们需要使用原子操作、 volatile关键字、ThreadLocal变量或者通过同步机制(如synchronized和Lock)来保护共享资源。 本学习资料包将覆盖以上所述的多线程基础、线程池原理、并发工具的使用以及...

Global site tag (gtag.js) - Google Analytics