一、背景以及概念
从上篇java多线程同步机制可以看出,想要编写出一个多线程安全的程序的困难的。但是为了让线程共享资源,必须小心地对共享资源进行同步。同步肯定会带来一定的延
迟,另一方面又要注意对象的锁定和释放,还要避免产生死锁。
我们还可以从另一个角度来考虑多线程共享资源的问题,既然共享资源这么困难,那么就干脆不要共享,何不为每个线程创造一个资源的复本。将每一个线程存取数据的行为
加以隔离,实现的方法就是给予每个线程一个特定空间来保管该线程所独享的资源。ThreadLocal就可以解决这样的问题。ThreadLocal为解决多线程并发问题提供了一个新的思
路。
ThreadLocal顾名思义,local variable(线程局部变量)的意思。它的功用就是为每个使用该变量的线程都提供一个变量值的副本,每一个线程都可以
独立的改变自己的副本,而不会和其他线程的副本产生冲突。
二、创建一个ThreadLocal变量
private
ThreadLocal
myThreadLocal =
new
ThreadLocal();
或者带泛型的变量
private
ThreadLocal
myThreadLocal =
new
ThreadLocal<String>();
三、ThreadLocal组成
它主要由四个方法组成initialValue(),get(),set(T),remove()。其中 initialVlue()方法是一个protected方法,显然是为了子类重写而特意设计的,该方法返回当前线程在该线
程局部变量的初始值。在一个线程第1次调用get()或者set(Object)时才执行,并且仅执行1次,ThreadLocal中的缺省实现直接返回一个null。
private ThreadLocal
myThreadLocal = new ThreadLocal<String>()
{ |
|
@Override |
|
protected String
initialValue() { |
|
return "This
is the initial value" ; |
|
} |
|
|
}; |
三、ThreadLocal原理
看ThreadLocal的源码会发现,它的实现原理就是在ThreadLocal中有一个ThreadLocalMap用来存放每一个线程的变量副本,就像这种形式:
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);
}
values.put(Thread.currentThread(), newValue);
return o ;
}
public Object initialValue()
{
return null;
}
}