初识ThreadLocal
近期公司在进行Java开发者的招聘活动,当中有一道面试题是这种:“请简单描写叙述一下ThreadLocal类的作用。” 结果发现有非常多的面试者没有听说过ThreadLocal或者听说过却不知道这个类到底是用来做什么的。
因此这里写一篇博客来介绍一下ThreadLocal这个类。
而它的目的也正是为了解决多线程并发訪问共享数据的问题。
通过阅读ThreadLocal的源代码并了解它解决并发问题的思路,开发者能够更好的理解代码中遇到的多线程bug,更不用提那些在项目开发中须要用到多线程编程的开发者了。
因此,不论你是否用到了ThreadLocal类,都非常有必要学习一下它。
”
2. 共享状态不可变。 如果某条数据被多线程共享。然而该数据是不可变数据。那么它便没有多线程问题。
举例来说: Java中的String类型就是不可变的,因此String的共享并不会导致多线程安全问题。
随意的数据都由某个线程独占,不与其它线程分享,因此也不会出现多线程问题。
这是最主要的想法,不论什么一本Java多线程编程的书都会具体描写叙述怎样在Java中使用同步,这里不再赘述。
既然没有了多线程的共享状态。也就无所谓是否线程安全了。
因此不能简单的说ThreadLocal是否线程安全,这个问题事实上没有意义。
- /**
- * Returns the value in the current thread's copy of this
- * thread-local variable. If the variable has no value for the
- * current thread, it is first initialized to the value returned
- * by an invocation of the {@link #initialValue} method.
- *
- * @return the current thread's value of this thread-local
- */
- 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();
- }
- /**
- * Sets the current thread's copy of this thread-local variable
- * to the specified value. Most subclasses will have no need to
- * override this method, relying solely on the {@link #initialValue}
- * method to set the values of thread-locals.
- *
- * @param value the value to be stored in the current thread's copy of
- * this thread-local.
- */
- public void set(T value) {
- Thread t = Thread.currentThread();
- ThreadLocalMap map = getMap(t);
- if (map != null)
- map.set(this, value);
- else
- createMap(t, value);
- }
我们来看一个在Hibernate中使用ThreadLocal的样例:
- private static ThreadLocal<Connection> connectionHolder
- = new ThreadLoca<Connection>() {
- public Connection initialValue() {
- return DriverManager.getConnection(DB_URL);
- }
- };
- public static Connection getConnection() {
- return ConnectionHolder.get();
- }
上面的样例是一个最经典的ThreadLocal使用案例: 在单线程中创建一个单例变量。并在程序启动时初始化该单例变量,从而避免在调用每个方法时都要传递该变量。然而该单例可能并非线程安全的,因此,当多线程应用程序在没有互相协作的情况下,能够通过将该单例变量保存到ThreadLocal中。以确保每个线程都拥有属于自己的实例。
在这里,一个更好理解的说法便是:该单例是一个线程内单例,在多线程应用中,每一个线程里都有一个该单例。
通过学习ThreadLocal,我们可以对正确的在项目中使用它。同一时候。也可以帮助我们对多线程编程有一个更深的认识.
(该文同一时候发表在http://mabusyao.iteye.com/blog/2224898)
初识ThreadLocal的更多相关文章
- 初识Java ThreadLocal
转载自:https://www.cnblogs.com/dreamroute/p/5034726.html ThreadLocal翻译成中文比较准确的叫法应该是:线程局部变量. 这个玩意有什么用处,或 ...
- ThreadLocal详解,ThreadLocal源码分析,ThreadLocal图解
本文脉路: 概念阐释 ----> 原理图解 ------> 源码分析 ------> 思路整理 ----> 其他补充. 一.概念阐述. ThreadLocal 是一个为 ...
- Java并发编程:ThreadLocal的使用以及实现原理解析
前言 前面的文章里,我们学习了有关锁的使用,锁的机制是保证同一时刻只能有一个线程访问临界区的资源,也就是通过控制资源的手段来保证线程安全,这固然是一种有效的手段,但程序的运行效率也因此大大降低.那么, ...
- ThreadLocal简单理解
在java开源项目的代码中看到一个类里ThreadLocal的属性: private static ThreadLocal<Boolean> clientMode = new Thread ...
- Android线程管理之ThreadLocal理解及应用场景
前言: 最近在学习总结Android的动画效果,当学到Android属性动画的时候大致看了下源代码,里面的AnimationHandler存取使用了ThreadLocal,激起了我很大的好奇心以及兴趣 ...
- Threadlocal使用Case
Threadlocal能够为每个线程分配一份单独的副本,使的线程与线程之间能够独立的访问各自副本.Threadlocal 内部维护一个Map,key为线程的名字,value为对应操作的副本. /** ...
- Android动画效果之初识Property Animation(属性动画)
前言: 前面两篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画).Frame Animation(逐帧动画)Andr ...
- 多线程映射工具——ThreadLocal
ThreadLocal相当于一个Map<Thread, T>,各线程使用自己的线程对象Thread.currentThread()作为键存取数据,但ThreadLocal实际上是一个包装了 ...
- ThreadLocal 工作原理、部分源码分析
1.大概去哪里看 ThreadLocal 其根本实现方法,是在Thread里面,有一个ThreadLocal.ThreadLocalMap属性 ThreadLocal.ThreadLocalMap t ...
随机推荐
- Linux远程远程控制程序TeamViewer
TeamViewer 软件我就不介绍了,相信进行远程管理的人都知道它. 1.安装: Linux个发行版因软件管理方式不同而不同,先通过软件管理从自己的软件仓库进行搜索安装如果有就进行安装,没有通过官网 ...
- MySQL Pool
创建连接池 function SqlPool() { this.flag = true;//是否连接过 this.pool = mysql.createPool({ host : 'localhost ...
- Mark Compact GC (Part two :Two-Finger)
目录 Two-Finger算法 前提 概要 步骤一:移动对象 步骤二:更新指针 优缺点 表格算法 概要 步骤一:移动对象群 和 构筑间隙表格 移动对象群 构筑间隙表格 步骤二:更新指针 优缺点 Two ...
- 洛谷—— P1086 花生采摘
https://www.luogu.org/problem/show?pid=1086#sub 题目描述 鲁宾逊先生有一只宠物猴,名叫多多.这天,他们两个正沿着乡间小路散步,突然发现路边的告示牌上贴着 ...
- css3中关于伪类的使用
目标: css中after伪类,last-child伪类的使用.以及部分css3的属性. 过程: 在制作导航时.常常会遇到在每个li后面加入一个切割符号,到最后一个元素的时候,切割符就会去掉的一种效果 ...
- 谈谈 Struts2 的拦截器
套话 相信非常多人都用过 Struts2 了,当然,对 Struts2 的原理也都比較了解.之前在一个项目中就已经用到了,当初的理解也不过局限在应用的层面上,对于更深层次的原理.机制,了解的并非非常多 ...
- 用MediaRecorder实现简单的录像功能
思路:定义一个SurfaceView用来显示预览,在SurfaceHolder的回调中用Camera对象启动预览.然后调用MediaRecorder来录像.仅仅是实现了简单的录像開始和停止功能.顶部能 ...
- Java Swing设置主窗体位置居中方法
01.第一种方法 int windowWidth = frame.getWidth(); //获得窗体宽 int windowHeight = frame.getHeight(); //获得窗体高 ...
- UDP连接调用connect()函数
UDP是一个无连接的协议,它没有像TCP中EOF之类的东西. 8.11 UDP的connect函数 除非套接字已连接,否则异步错误是不会反悔到UDP套接字的. 我们确实能够给UDP套接字调用conne ...
- 【OC学习-8】存取器方法?getter和setter?事实上就是赋值和返回值的两种函数
我们在声明类的时候,有实例变量+方法(函数),这些实例变量假设默认的话都是protected类型,一般无法直接訪问.更别提赋值和调用了,所以就产生了两种函数,getter函数就是可以返回实例变量的值, ...