ThreadLocal作用,总结起来一句话就是,让线程轻松的就可以获得独立实例,不用在线程创建的时候传入。
ThreadLocal在资源实例里使用(创建一个方法A,A创建一个实例并与ThreadLocal绑定),用来在run()方法中调用该方法A。
spring中访问数据库的模板使用了ThreadLocal技术,数据库资源本来是非线程安全的,如果使用synchronized进行同步,大大降低了并发访问。
ThreadLocal,实际上应该理解为Thread的局部变量。
把非线程安全的变量与current的线程绑定。每个访问的线程拿到的都是属于自己的一份。
多个线程之间并不是共享实例,而是利用ThreadLocal给每个线程绑定一个实例。
这样在某个线程调用到该实例时,会先去判断该线程是否已经绑定了该实例,如果没有,则获取或创建一个新的实例。
同时,如果某个线程结束了,其相应的绑定的实例也会被回收。
public class CountNum {
private static ThreadLocal<CountNum> countNumLocals
= new ThreadLocal<CountNum>();
public static CountNum getCountNum(){
if (CountNum.countNumLocals.get() == null) {
System.out.println("here");
CountNum.countNumLocals.set(new CountNum());
}
return CountNum.countNumLocals.get();
}
private int i = 0;
public void increase(){
++i;
System.out.println(Thread.currentThread().getName() + " : " + i);
}
public void decrease(){
--i;
System.out.println(Thread.currentThread().getName() + " : " + i);
}
public static void main(String[] args) throws InterruptedException{
Thread.sleep(1000);
Thread t1 = new Thread(new Increase());
Thread t2 = new Thread(new Increase());
Thread t3 = new Thread(new Decrease());
t1.start();
t2.start();
t3.start();
}
}
public class Increase implements Runnable{
public Increase(){
}
@Override
public void run() {
CountNum countNum = CountNum.getCountNum();
for(int i = 0; i< 50; i++){
countNum.increase();
}
}
}
public class Decrease implements Runnable {
public Decrease(){
}
@Override
public void run() {
CountNum countNum = CountNum.getCountNum();
for(int i = 0; i< 50; i++){
countNum.decrease();
}
}
}
从上面的实例可以看到,如果有多个线程执行Increase 的run()方法,如果不用ThreadLocal, countNum实例只能通过类似在构造方法中传入的方法。
但这样有很多缺点:
1)此实例就成了全局变量,当线程结束时,不能自动回收。
2)实例的传入是个问题,何时传入,在什么地方传入,在实际项目中(如servlet)将变得复杂。 要想使实例独立,必须在每个线程启动的时候传入实例。
在web项目中,多线程启动的地方是在web服务器内,我们没法去修改代码传入实例。
在线程的run()中传入实例,将造成多个线程并发访问的状态。 实例不能独立,并且需要考虑并发的情况。
分享到:
相关推荐
NULL 博文链接:https://bijian1013.iteye.com/blog/2380233
NULL 博文链接:https://xxxxxfsadf.iteye.com/blog/518275
NULL 博文链接:https://yizhenn.iteye.com/blog/2293339
6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.1.1. @Configurable object的单元测试 6.8.1.2. 多application context情况下的处理 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来...
主要介绍了详解Spring Cloud中Hystrix 线程隔离导致ThreadLocal数据丢失,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...
运行在tomcat容器中的ThreadLocal容易产生的问题ThreadLocal在tomcat容器中的的生命周期并不等于web request的生命周期,所以(以下讨论的是tomcat容器中使用ThreadLocal),所以ThreadLocal不应保存与请求会影响的...
12.2 在Spring中使用Hibernate 12.2.1 配置SessionFactory 12.2.2 使用HibernateTemplate 12.2.3 处理LOB类型数据 12.2.4 添加Hibernate事件监听器 12.2.5 使用原生Hibernate API 12.2.6 使用注解配置 12.2.7 事务...
6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. ...
6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...
6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. ...
Spring中BeanFactory和ApplicationContext的区别 谈谈Spring IOC的理解,原理与实现? bean的生命周期,详细看上面 SpringBoot自动装配的过程的原理: spring的缓存; spring是如何解决的循环依赖; BeanFactory和...
12.2 在Spring中使用Hibernate 12.2.1 配置SessionFactory 12.2.2 使用HibernateTemplate 12.2.3 处理LOB类型数据 12.2.4 添加Hibernate事件监听器 12.2.5 使用原生Hibernate API 12.2.6 使用注解配置 12.2.7 事务...
题目起的有些拗口了,简单说,这篇文章想要解释Spring为什么会选择使用ThreadLocal将资源和事务绑定到线程上,这背后有着什么样的起因和设计动机,通过分析帮助大家更清晰地认识Spring的线程绑定机制。访问任何带有...
Spring原理 2 Spring ioc 原理 3 Bean生命周期 3 Java反射 4 beanfactory和applicationcontext 5 类装载器ClassLoader 6 Spring aop 原理 6 Aop代理 7 ...ThreadLocal 13 Spring TaskExecutor线程池 16
AopLogAopLog是基于SpringAop和ThreadLocal实现的一个对请求方法埋点记录与处理的日志工具包。设计目的和场景:使用Spring Aop拦截程序,基本上都是同一个小异,不想日后每个项目...在正式环境中,我并不想打印太多无意
在查阅大量多数据源配置资料和文章并结合工作实践的基础上开发了一个简单实用的spring boot动态多数据源demo,该demo主要功能如下: 自定义多数据源类MultiplyDataSource(继承HikariDataSource),通过多线程类...
数据源加载在基于DataProperteis的基础上配置了 master slave, 将它们配置成map,map中是多个数据源的主键和数据源属性的映射; 因此, 再通过线程隔离 ThreadLocal 动态数据源上下文来切换数据源; 切换这个操作...
springboot+springcloud+eureka+提供者消费者
java 学习整理文档 Spring框架并...使用ThreadLocal ,在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在 ThreadLocal 中(以空间换时间”),为每一个线程都提供了一份变量,因此可以同时访问而互不影响