ThreadLocal类很简单,只有4个方法
void set(Object value);
设置当前线程的线程局部变量的值
public Object get()
该方法返回当前线程所对应的线程局部变量
public void remove()
protected Object initialValue()
这个方法是一个延迟调用方法,在线程第一次调用get()或set(Object)时才执行,并且执行1次。ThreadLocal中默认实现直接返回一个Null
ThreadLocal是为解决多线程程序的并发问题而提出的,可以称之为线程局部变量。与一般的变量的区别在于,生命周期是在线程范围内的。
static变量是的生命周期与类的使用周期相同,即只要类存在,那么static变量也就存在。
那么一个 static 的 ThreadLocal会是什么样的呢?
看下面一个例子,
- public class SequenceNumber {
- private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>(){
- public Integer initialValue(){
- return 0;
- }
- };
- public int getNextNum(){
- seqNum.set(seqNum.get() + 1); //执行iniialValue
- return seqNum.get();
- }
- public static void main(String[] args){
- SequenceNumber sn = new SequenceNumber();
- TestClient t1 = new TestClient(sn);
- TestClient t2 = new TestClient(sn);
- TestClient t3 = new TestClient(sn);
- t1.start();
- t2.start();
- t3.start();
- t1.print();
- t2.print();
- t3.print();
- }
- private static class TestClient extends Thread{
- private SequenceNumber sn ;
- public TestClient(SequenceNumber sn ){
- this.sn = sn;
- }
- public void run(){
- for(int i=0; i< 3; i++){
- System.out.println( Thread.currentThread().getName() + " --> " + sn.getNextNum());
- }
- }
- public void print(){
- for(int i=0; i< 3; i++){
- System.out.println( Thread.currentThread().getName() + " --> " + sn.getNextNum());
- }
- }
- }
- }
下面是结果
- Thread-2 --> 1
- Thread-2 --> 2
- Thread-2 --> 3
- Thread-0 --> 1
- Thread-0 --> 2
- Thread-0 --> 3
- Thread-1 --> 1
- Thread-1 --> 2
- Thread-1 --> 3
- main --> 1
- main --> 2
- main --> 3
- main --> 4
- main --> 5
- main --> 6
- main --> 7
- main --> 8
- main --> 9
可以发现,static的ThreadLocal变量是一个与线程相关的静态变量,即一个线程内,static变量是被各个实例共同引用的,但是不同线程内,static变量是隔开的
public class JackyDao
{
private static ThreadLocal<Connection> connThreadLocal=new ThreadLocal<Connection>();
pubic static Connection getConnection()
{
if(connThreadLocal.get()==null)
{
Connection conn=ConnectionManager.getConnection();
connThreadLocal.set(conn);
return conn;
}
else
{
return connThreadLocal.get();
}
}
}