java中ThrealLocal的理解
java中threadlocal的理解
一、threadlocal的生命周期和ThreadLocalMap的生命周期
可以吧TreadLocal看做是一个map来使用,只不过这个map是指向当前线程中的threadLocals(ThreadLocalMap.class),这个threadLocals采用懒汉单例在一个线程中是唯一的。
Thread中的threadLocals属性,存放的是当前线程在不同TreadLocal实例中的值ThreadLocalMap<TreadLocal,T>
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);//return t.threadLocals;这里表示只有一个ThreadLocalMap副本
if (map != null)//采用懒汉模式
map.set(this, value);
else
createMap(t, value);//t.threadLocals = new ThreadLocalMap(this, firstValue);
}
可以通过查看当前线程中的threadLocals变量,来看当前线程持有多少个threadLocal,以及存的值。
ThreadLocalMap实例的生命周期随着线程的结束而结束,因为ThreadLocalMap实例的唯一引用只存在当前线程中。ThreadLocal的生命周期,需要gc来决定,因为他的引用可能存在于多个线程中,此引用为弱引用。
弱引用的存在,导致可能内存泄露。当threadlocal=null,没有任何强引用实例指向threadLocals中的key本来指向的threadlocal实例,gc回收threadlocal,导致val永远不会被释放。采用以下代码来取代=null的操作,用remove函数来清除,threadLocals。
ThreadLocal local1 = new ThreadLocal();
local.remove();
二、ThreadLocal的作用
对于那些需要数据隔离,可以用ThreadLocal。
对于一个线程中的一个ThreadLocal只能存一个T类型的数据。(T为泛型)
ThreadLocal是线程安全的,所以可以用来封装线程不安全的实例,不同线程之间新创建实例,保证线程安全。(另一种模式就是单例模式。)
三、threadlocal示例
- 比较经典的例子就是github中的PageHelper中保存Page信息的时候使用了ThreadLocal。考虑到数据的同步,已经一个线程只会顺序执行sql语句。
protected static final ThreadLocal<Page> LOCAL_PAGE = new ThreadLocal();
protected static void setLocalPage(Page page) {
LOCAL_PAGE.set(page);
}
- AopContext
在同一个类中调用方法,导致aop不生效。原因是aop生效是调用的代理类,直接调用被代理类会无法触发切面。
@EnableAspectJAutoProxy(exposeProxy = true)//打开代理配置Appcontext
AopContext.currentProxy() //获取到当前类的代理类,可以进行强制转换
public abstract class AopContext {
private static final ThreadLocal<Object> currentProxy = new NamedThreadLocal("Current AOP proxy");//本质还是通过threadlocal实现
public AopContext() {
}
public static Object currentProxy() throws IllegalStateException {
Object proxy = currentProxy.get();
if (proxy == null) {
throw new IllegalStateException("Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.");
} else {
return proxy;
}
}
static Object setCurrentProxy(Object proxy) {
Object old = currentProxy.get();
if (proxy != null) {
currentProxy.set(proxy);
} else {
currentProxy.remove();
}
return old;
}
}
四、InheritableThreadLocal的扩展
- InheritableThreadLocal extends ThreadLocal
- 子线程可以使用InheritableThreadLocal可以拿到父亲线程的变量,父线程无法拿到子线程的
- 子线程对变量的修改,父线程不可见。子线程修改的父线程那边拷贝的副本
- init子线程的时候,对threadlocal中的值进行复制
class Thread{
private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc) {
......略
Thread parent = currentThread();
if (parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
......略
}
}
- 和threallocal相比,只有map的引用不一样。
java中ThrealLocal的理解的更多相关文章
- java中threadlocal的理解
[TOC] #java中threadlocal的理解##一.threadlocal的生命周期和ThreadLocalMap的生命周期可以吧TreadLocal看做是一个map来使用,只不过这个map是 ...
- 谈谈我对Java中CallBack的理解
谈谈我对Java中CallBack的理解 http://www.cnblogs.com/codingmyworld/archive/2011/07/22/2113514.html CallBack是回 ...
- 沉淀再出发:关于java中的AQS理解
沉淀再出发:关于java中的AQS理解 一.前言 在java中有很多锁结构都继承自AQS(AbstractQueuedSynchronizer)这个抽象类如果我们仔细了解可以发现AQS的作用是非常大的 ...
- Java中hashcode的理解
Java中hashcode的理解 原文链接http://blog.csdn.net/chinayuan/article/details/3345559 怎样理解hashCode的作用: 以 java. ...
- 关于java中多态的理解
java三大特性:封装,继承,多态. 多态是java的非常重要的一个特性: 那么问题来了:什么是多态呢? 定义:指允许不同类的对象对同一消息做出响应.即同一消息可以根据发送对象的不同而采用多种不同的行 ...
- Java中泛型的理解
Java中的泛型,本质上来说,就是是参数化类型,就是说所操作的数据类型被指定为一个参数,而不是确定的某种类型.这种数据类型可以用在类.接口和方法创建中.即泛型类.泛型接口.泛型方法.这样说可能不够生动 ...
- 浅谈对java中锁的理解
在并发编程中,经常遇到多个线程访问同一个 共享资源 ,这时候作为开发者必须考虑如何维护数据一致性,在java中synchronized关键字被常用于维护数据一致性.synchronized机制是给共享 ...
- Java中面向对象的理解
按照惯例,先做一个简单的介绍,现在开始学习 Thinging in Java 4 ,一边看,一边记录,我都不想给自己设定时间安排了,毕竟很少实现过.所以就这样吧!不定期的更新,我都会放到博客中的. 所 ...
- java中锁的理解
在并发编程中,经常遇到多个线程访问同一个 共享资源 ,这时候作为开发者必须考虑如何维护数据一致性,在java中synchronized关键字被常用于维护数据一致性.synchronized机制是给共享 ...
随机推荐
- 足球动图gif(二)
- 网课神器之obs-studio的安装使用
obs-studio 首先,下载obs-studio安装文件,然后点击安装. 建议安装完后直接跳过配置,然后进入文件-设置-通用-系统托盘-勾选"总是最小化到系统托盘,而不是任务栏" ...
- javascript : 复杂数据结构拷贝实验
数组深拷贝看起来很简单. array.concat()就行了. 但是,如果数组里有对象呢? 实际上,你以为你拷贝了对象,但实际上你只拷贝了对象的引用(指针)! 我们可以做个试验. // test le ...
- 6.ALOHA协议
动态媒体接入控制/多点接入特点:信道并非在用户通信时固定分配给用户. 一.纯ALOHA协议 纯 ALOHA协议思想:不监听信道,不按时间槽发送,随机重发.想发就发 二.时隙ALOHA协议 时隙 ALO ...
- p70_域名解析系统DNS
一.DNS作用 二.域名 www.cskaoyan.com. www 三级域名 cskaoyan 二级域名 com 顶级域名 三.域名服务器 根域名服务器:知道所有顶级域名服务器的域名和ip地址 顶级 ...
- 做软件测试要月入20k?听听腾讯大牛怎么说
作者:兰色链接:https://www.zhihu.com/question/373819487/answer/1183309514来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...
- 关于IDEA的一些快捷键操作
shift+F6修改实体类中的属性会重构代码
- Kafka 入门(一)--安装配置和 kafka-python 调用
一.Kafka 简介 1.基本概念 Kafka 是一个分布式的基于发布/订阅消息系统,主要应用于大数据实时处理领域,其官网是:http://kafka.apache.org/.Kafka 是一个分布式 ...
- 如何查看预收录在arXiv上论文的LaTeX源文件并编译
arXiv 是一个收集物理学.数学.计算机科学与生物学论文预印本的网站. 对于理科生来说,经常需要在上面搜索下载一些论文,正常情况下,一般人下载的只是 pdf 文件,其实可以在 arXiv 上下载编译 ...
- ls -bash: ls: command not found
ls -bash: ls: command not found原因:在设置环境变量时,编辑profile文件没有写正确,导致在命令行下 ls等命令不能够识别.解决方案: export PATH=/us ...