一:ThreadLocal类的例子:
某一线程中的局部变量会被其他线程所改写,所以有了ThreadLocal类,可以用这个类来保存局部变量,以保证局部变量的安全!
以下两个例子其中之一使用了ThreadLocal类,另一个未用,注意观察其结果的不同:
class UnsafeTask implements Runnable{
private Date startDate;
@Override
public void run(){
startDate=new Date();
System.out.printf("Starting Thread: %s:%s\n",Thread.currentThread().getId(),startDate);
try {
TimeUnit.SECONDS.sleep((long) Math.rint(Math.random()*10));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Thread Finished: %s:%s\n", Thread.currentThread().getId(),startDate);
}
}
public class Test_UnsafeTask{
public static void main(String[] args){
UnsafeTask task=new UnsafeTask();
for(int i=0;i<10;i++){
Thread thread=new Thread(task);
thread.start();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
结果:
Starting Thread: 9:Tue Oct 14 20:31:36 CST 2014
Starting Thread: 10:Tue Oct 14 20:31:38 CST 2014
Thread Finished: 9:Tue Oct 14 20:31:38 CST 2014
Starting Thread: 11:Tue Oct 14 20:31:40 CST 2014
Thread Finished: 10:Tue Oct 14 20:31:40 CST 2014
Thread Finished: 11:Tue Oct 14 20:31:40 CST 2014
public class Test_SafeTask {
public static void main(String[] args) {
SafeTask task = new SafeTask();
for (int i = 0; i < 3; i++) {
Thread thread=new Thread(task);
thread.start();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class SafeTask implements Runnable {
// 线程局部变量机制解决局部变量不安全的特性
private static ThreadLocal<Date> startDate = new ThreadLocal<Date>() {
protected Date initialValue() {
return new Date();
}
};
@Override
public void run() {
System.out.printf("Starting Thread: %s : %s\n", Thread.currentThread()
.getId(), startDate.get());
try {
TimeUnit.SECONDS.sleep(Math.round(Math.random() * 10));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Thread Finished: %s : %s\n", Thread.currentThread()
.getId(), startDate.get());
}
}
其结果:
Starting Thread: 9 : Tue Oct 14 20:33:02 CST 2014
Thread Finished: 9 : Tue Oct 14 20:33:02 CST 2014
Starting Thread: 10 : Tue Oct 14 20:33:04 CST 2014
Starting Thread: 11 : Tue Oct 14 20:33:06 CST 2014
Thread Finished: 11 : Tue Oct 14 20:33:06 CST 2014
Thread Finished: 10 : Tue Oct 14 20:33:04 CST 2014
二:ThreadLocal类中的主要方法:
1.泛化的无参构造器,
2.
大家看看吧,不解释了,
3.ThreadLocal有一个静态的内部类ThreadLocalMap,通过这个map对线程中的局部变量进行保存,其key为当前线程的id,value既是你所保存的变量,即初始化,改,查,移除都必须通过这个Thread.currentThread().getId()的id进行,从而保证了局部变量的安全。我们只看下set(T value)的源码就行:
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
4.ThreadLocal这个类是 @author Josh Bloch and Doug Lea写的,大家可以去百度下这个作者。