ThreadLocal使用分析
来源:互联网 发布:军事机构的域名是 编辑:程序博客网 时间:2024/05/22 06:57
关于ThreadLocal的用法在进行了诸多的研究分析之后,终于有所斩获,掌握了其本质的若干用法,先总结如下:
- 在对运行同一段代码的多线程程序中,用以实现同一个线程之内同一个变量的同步,避免其多个线程之间彼此的干扰。效率相对于synchronized而言,有相当的提升。
- 本质上讲,其就是实现单一线程的私有变量
关于其实现,摘引klyuan(javaeye)上的例子,如下,很好的说明了ThreadLocal的实现方式,当然你也可以参考JDK源代码中的实现。本质上,其就是一个同步的HashMap而已,可以为线程,value为所定义的局部变量。
- public class ThreadLocal
- {
- private Map values = Collections.synchronizedMap(new HashMap());
- public Object get()
- {
- Thread curThread = Thread.currentThread();
- Object o = values.get(curThread);
- if (o == null && !values.containsKey(curThread))
- {
- o = initialValue();
- values.put(curThread, o);
- }
- return o;
- }
- public void set(Object newValue)
- {
- values.put(Thread.currentThread(), newValue);
- }
- public Object initialValue()
- {
- return null;
- }
- }
应用分析,一个同事将一段代码给我,说其中关于ThreadLocal的set(null)这行代码,如果注释掉,会出现什么情况,详细代码如下:
我们可以看到有2行关于local和local_tr的set(null)的方法如果被注释掉的情况,我们可以推测会出现什么样的情况。
/** *//**
* Import Package missing for space
**/
public class HibernateUtil ...{
private static SessionFactory sf;
private static ThreadLocal local = new ThreadLocal();
private static ThreadLocal local_tr = new ThreadLocal();
static...{
Configuration conf = new Configuration();
conf = conf.configure("/hibernate.cfg.xml");
sf = conf.buildSessionFactory();
}
public static Session getSession()...{
System.out.println("threadLocalid=="+local);
Session session = null;
if(local.get()==null)...{
session = sf.openSession();
System.out.println("---------session is created------------");
local.set(session);
}else...{
session = (Session)local.get();
}
return session;
}
public static void begin()...{
Session session = (Session)local.get();
Transaction ts = null;
if(local_tr.get()==null)...{
ts = session.beginTransaction();
local_tr.set(ts);
}
}
public static void commit()...{
Transaction tr = (Transaction)local_tr.get();
tr.commit();
local_tr.set(null); // this line is removed,then what will happen?
System.out.println("---------transaction is commited------------");
}
public static void rollback()...{
Transaction tr = (Transaction)local_tr.get();
tr.rollback();
System.out.println("---------transaction is rollbacked------------");
}
public static void close()...{
Session session = (Session)local.get();
if(session!=null)...{
session.close();
System.out.println("---------session is destroyed------------");
}
local.set(null); // this line is removed, then what will happen?
}
}
* Import Package missing for space
**/
public class HibernateUtil ...{
private static SessionFactory sf;
private static ThreadLocal local = new ThreadLocal();
private static ThreadLocal local_tr = new ThreadLocal();
static...{
Configuration conf = new Configuration();
conf = conf.configure("/hibernate.cfg.xml");
sf = conf.buildSessionFactory();
}
public static Session getSession()...{
System.out.println("threadLocalid=="+local);
Session session = null;
if(local.get()==null)...{
session = sf.openSession();
System.out.println("---------session is created------------");
local.set(session);
}else...{
session = (Session)local.get();
}
return session;
}
public static void begin()...{
Session session = (Session)local.get();
Transaction ts = null;
if(local_tr.get()==null)...{
ts = session.beginTransaction();
local_tr.set(ts);
}
}
public static void commit()...{
Transaction tr = (Transaction)local_tr.get();
tr.commit();
local_tr.set(null); // this line is removed,then what will happen?
System.out.println("---------transaction is commited------------");
}
public static void rollback()...{
Transaction tr = (Transaction)local_tr.get();
tr.rollback();
System.out.println("---------transaction is rollbacked------------");
}
public static void close()...{
Session session = (Session)local.get();
if(session!=null)...{
session.close();
System.out.println("---------session is destroyed------------");
}
local.set(null); // this line is removed, then what will happen?
}
}
如果基于local(Session的局部变量)不进行set(null)的话,会出现所有的thread都基于获取同一个session的情况。
如果local_tr(Transaction的局部变量)不进行set(null)的话,对于基于同一个session的线程而言,其只可以进行一次的事务提交,后续都将无法进行,因为每次进行之前会进行局部变量的有效判断。
总结: ThreadLocal是一个有效的多线程局部变量工具,当然也是一把双刃剑,用好的话可以制敌,反之则可能祸己。要用好ThreadLocal,我们只需记住其本质:线程局部变量;其实现的本质是一个基于同步的HashMap就可以了。每一个线程都是用于该变量的一个独立副本。
- ThreadLocal使用分析
- ThreadLocal 使用分析
- ThreadLocal的分析与使用
- ThreadLocal使用和源码分析
- JAVA里ThreadLocal的使用与分析
- ThreadLocal源码分析与使用场景
- ThreadLocal基本使用和源码分析
- ThreadLocal 分析
- ThreadLocal 分析
- ThreadLocal-分析
- ThreadLocal-分析
- ThreadLocal分析
- ThreadLocal分析
- Spring源码分析【6】-ThreadLocal的使用和源码分析
- ThreadLocal使用
- ThreadLocal使用
- ThreadLocal使用
- ThreadLocal使用
- asp.net页面间数据传递(总结篇)
- 小技巧--自动隐藏红叉叉(图片显示失败)
- 关于数字的智力测试
- asp.net必懂题
- 类成员的访问修饰符和可访问性
- ThreadLocal使用分析
- wince内存分配
- 值类型与引用类型的区别
- 动态改变数据库表结构的sql存储过程
- 1、1、2、3、5、8、13、21、34...... (用递归算法)
- 解析SQL Server 2008的精妙之处
- 学习.Net的经典网站
- C#中的泛型(2.0)
- c#中的反射