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机制是给共享 ...
随机推荐
- Python函数05/内置函数/闭包
Python函数05/内置函数/闭包 目录 Python函数05/内置函数/闭包 内容大纲 1.内置函数(二) 2.匿名函数及内置函数(重要) 3.闭包 4.今日总结 5.今日练习 内容大纲 1.内置 ...
- python面向对象07/异常处理
python面向对象07/异常处理 目录 python面向对象07/异常处理 1. 异常错误分类 2. 什么是异常? 3. 异常处理 4. 为什么要有异常处理 5. 异常处理的两种方式 1.if判断 ...
- (八) SpringBoot起飞之路-整合Shiro详细教程(MyBatis、Thymeleaf)
兴趣的朋友可以去了解一下前几篇,你的赞就是对我最大的支持,感谢大家! (一) SpringBoot起飞之路-HelloWorld (二) SpringBoot起飞之路-入门原理分析 (三) Sprin ...
- 德布鲁因序列与indexing 1
目录 写在前面 标记left-most 1与right-most 1 确定位置 德布鲁因序列(De Bruijn sequence) 德布鲁因序列的使用 德布鲁因序列的生成与索引表的构建 参考 博客: ...
- Postman接口测试实战分享,这5个问题你必须得知道!【软件测试工程师经验分享】
在我们日常的测试工作中,接口测试其实很普遍,无论你是做什么测试,功能.自动化亦或是性能测试,都会或多或少接触到接口. 最近也有许多人来询问我:接口测试怎么测?接口测试工具有哪些? 下面我来帮你一一剖析 ...
- Oracle数据泵详解
一.EXPDP和IMPDP使用说明 Oracle Database 10g引入了最新的数据泵(Data Dump)技术,数据泵导出导入(EXPDP和IMPDP)的作用 1)实现逻辑备份和逻辑恢复. 2 ...
- Python Ethical Hacking - BACKDOORS(8)
Cross-platform hacking All programs we wrote are pure python programs They do not rely on OS-specifi ...
- UC 网盘:我又回来了
普通用户不限速下载,免费 10GB 空间,支持离线下载 这个域名非常厉害,某里挑选域名果然是值得称赞的.直接使用手机号即可注册登录,默认赠送 10GB 空间.不过目前好像没看到有电脑客户端,电脑上下载 ...
- 设计模式:fly weight模式
目的:通过共享实例的方式来避免重复的对象被new出来,节约系统资源 别名:享元模式 例子: class Char //共享的类,轻量级 { char c; public: Char(char c) { ...
- 关于ajaxSubmit传递参数 后台接收为"参数,参数”的问题
问题: 用户名密码往后台提交的时候,发现接收到的参数变成了下图 解决办法: 去掉ajaxSubmit的data属性 如下图 解释:因为ajaxSubmit在封装的时候会自动的从被form包裹的表单控件 ...