java 独立存储线程变量技术——ThreadLocal
来源:互联网 发布:微信数据怎么放到sd卡 编辑:程序博客网 时间:2024/05/21 18:23
在多线程编程中,我们使用锁(synchronized,ReentrantLock等)来确保多个线程共享的变量能被安全的访问。但是还有一些变量,我们希望每一个线程都能保存一份独立的值而不受其他线程的影响。这个时候我们就需要用到ThreadLocal这个类来完成相关操作。
ThreadLocal的作用
现有两个线程A和B,它们都能访问到一个变量str_c。在不经过任何处理时,str_c的值可以被A和B两个线程访问和修改。使用了ThreadLocal后将str_c作为一个线程的局部变量,对于每一个线程,通过ThreadLocal方法得到的str_c的值是该线程的str_c的值,这个值不会被其他线程修改,其他线程只能修改他们自己的str_c的值。在并发的代码中的任何一点我们都能访问ThreadLocal而获取str_c的值,但是获取的值是该线程的值,其他线程的str_c在这个时候被“屏蔽”了,一般情况下我们看不见且访问不到。
在工作项目中举例。在Java ee的springMVC框架中,我们在封装Controller时习惯于将request、response两个对象通过ThreadLocal封装,因为这两个对象在每个线程中的内容肯定不同,通过这种技术,可以确保在高并发情况下的安全性。
ThreadLocal与Synchronized比较
网上的部分博客对ThreadLocal与Synchronized的概念混淆不清。ThreadLocal的作用并不是取代Synchronized,这两种方法从初衷上就完全不同。不仅仅是初衷,这两种技术的实现方法也不同,不存在可比性。
ThreadLocal: 将每个线程持有的变量安全的存放起来,不被其他线程访问。
synchronized: 让多个线程并发访问的变量能够安全的被访问和操作。
ThreadLocal使用方法
ThreadLocal类本身并不是线程,这个类是用来创建并存放线程局部变量的。
ThreadLocal 提供了线程局部变量并且通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。 例如,以下类通过重写initialValue方法生成对每个线程唯一的局部标识符。线程 ID 是在第一次调用 UniqueThreadIdGenerator.getCurrentThreadId() 时分配的,在后续调用中不会更改。
import java.util.concurrent.atomic.AtomicInteger; public class UniqueThreadIdGenerator { private static final AtomicInteger uniqueId = new AtomicInteger(0); private static final ThreadLocal < Integer > uniqueNum = new ThreadLocal < Integer > () { @Override protected Integer initialValue() { return uniqueId.getAndIncrement(); } }; public static int getCurrentThreadId() { return uniqueNum.get(); } }
ThreadLocal实现原理
ThreadLocal的实现方法有些复杂,愚以为这个技术可以不采用Map的方式来存放,其他的键值对存放方式也未尝不可,但是jdk采用的方法肯定有他正确的道理。ThreadLocal存放局部变量的底层实现主要涉及到三个类:ThreadLocal、ThreadLocalMap、Thread。
ThreadLocal:
在这个类中,每当调用set方法传入值时先获得当前线程Thread对象,在Thread对象的私有变量中查看ThreadLocal.ThreadLocalMap类对象是否为空,如果不为空,将值和threadLocal的this对象传入ThreadLocalMap类中。
ThreadLocalMap:
ThreadLocalMap是TheadLocal的静态内部类,这也能够解释为什么在Thread类中ThreadLocalMap可以通过ThreadLocal.ThreadLocalMap(外部类.内部类)的方式声明。此类是一个简单实现的Map映射表和java集合框架中的Map类无关系。当有值传入时将线程对象和值以键值对的形式存放。
Thread:
这个类是当前线程类,其中包含ThreadLocal.ThreadLocalMap类型的私有变量,用该变量来存放本线程的局部变量,从而达到其他线程不能访问的效果。
- java 独立存储线程变量技术——ThreadLocal
- 线程本地存储—ThreadLocal,map实现
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java线程(篇外篇):线程本地变量ThreadLocal
- Java并发编程---ThreadLocal(线程本地变量、线程本地存储)
- java学习——ThreadLocal 线程局部 (thread-local) 变量的使用
- Java线程范围变量——ThreadLocal的模拟和解释
- java实现线程局部变量:ThreadLocal
- mysql各种引擎特性对比表
- opencv3UMat介绍,以及测试比较opencl,cuda性能
- Vue+axios 实现http拦截及路由拦截实例
- 程序员最核心的竞争力是什么?
- android隐藏标题栏
- java 独立存储线程变量技术——ThreadLocal
- 利用CombineFileInputFormat合并小文件
- GPIO 输入—按键检测
- protobuf入门教程(四):repeated限定修饰符
- 数据类型及数据结构资料
- weblogic被root重启后出现 java.lang.ClassCastException
- vue2.0之axios使用详解(一)
- Nginx增加自定义域名配置服务
- 51NOD 1806 wangyurzee的树(容斥原理 + 组合数学)