一:先说下ThreadLocal的作用总结吧:
??????? 当线程并发时,使用ThreadLocal在保证每个线程拥有自己的独立对象,线程间互不影响。
?
二:在说下ThreadLocal和Synchronized关键字对线程并发时锁定同意操作对象的区别
??????? 前者线程并发拥有自己独立对象,做到操作对象的安全,但是它每个线程都会new一个操作对象的实例,这样一来,就损失了系统耗费内存的问题,但是性能有所提升!(以空间换时间)
??????? 后者线程并发时可以用Synchronized关键字来对线程来同步执行,但是它只能单个线程执行,阻塞其他线程,这样一来,就损失了系统的性能,但是系统内存占用问题有所提高!(以时间换空间)
?
三:我们来看下ThreadLocal应用的demo
public class Student { private int age = 0; // 年龄 public int getAge() { return this.age; } public void setAge(int age) { this.age = age; } } public class ThreadLocalDemo implements Runnable { // 创建线程局部变量studentLocal,在后面你会发现用来保存Student对象 private final static ThreadLocal studentLocal = new ThreadLocal(); public static void main(String[] agrs) { ThreadLocalDemo td = new ThreadLocalDemo(); Thread t1 = new Thread(td, "a"); Thread t2 = new Thread(td, "b"); t1.start(); t2.start(); } public void run() { // TODO Auto-generated method stub accessStudent(); } public void accessStudent() { // 获取当前线程的名字 String currentThreadName = Thread.currentThread().getName(); System.out.println(currentThreadName + " is running!"); // 产生一个随机数并打印 Random random = new Random(); int age = random.nextInt(100); System.out.println("thread " + currentThreadName + " set age to:" + age); // 获取一个Student对象,并将随机数年龄插入到对象属性中 Student student = getStudent(); student.setAge(age); System.out.println("thread " + currentThreadName + " first read age is:" + student.getAge()); try { Thread.sleep(500); } catch (InterruptedException ex) { ex.printStackTrace(); } System.out.println("thread " + currentThreadName + " second read age is:" + student.getAge()); } protected Student getStudent() { // 获取本地线程变量并强制转换为Student类型 Student student = (Student) studentLocal.get(); // 线程首次执行此方法的时候,studentLocal.get()肯定为null if (student == null) { // 创建一个Student对象,并保存到本地线程变量studentLocal中 student = new Student(); studentLocal.set(student); } return student; } } a is running! b is running! thread b set age to:15 thread a set age to:22 thread b first read age is:15 thread a first read age is:22 thread b second read age is:15 thread a second read age is:2 // 从得到的结果可以看出,线程之间的Student对象在每个线程中都拥有一个,做到互不干扰!
?为加强对ThreadLocal的认识,下面来看一个hibernate中典型的ThreadLocal的应用:
private static final ThreadLocal threadSession = new ThreadLocal(); public static Session getSession() throws InfrastructureException { Session s = (Session) threadSession.get(); try { if (s == null) { s = getSessionFactory().openSession(); threadSession.set(s); } } catch (HibernateException ex) { throw new InfrastructureException(ex); } return s; }
?我们通过以上例子,不难看出ThreadLocal的应用场合,最适合的是按线程多实例(每个线程对应一个实例)的对象的访问,并且这个对象很多地方都要用到。
??????????????????????????????????????????
最后补充下,ThreadLocal常用的方法
T get()
????????? 返回此线程局部变量的当前线程副本中的值。
protected? T initialValue()
????????? 返回此线程局部变量的当前线程的初始值。
void remove()
????????? 移除此线程局部变量的值。
void set(T value)
????????? 将此线程局部变量的当前线程副本中的值设置为指定值。
原文:http://zliguo.iteye.com/blog/2248548