//以下代码存在问题
public class ThreadLocalDemo {
//private static ThreadLocal<String> tl = new ThreadLocal<String>(); //①
private String name; //线程不安全的变量
public String getName() {
return name;
//return tl.get(); //②
}
public void setName(String name) {
this.name = name;
//tl.set(name); //③
}
public static void main(String[] args) {
ThreadLocalDemo demo = new ThreadLocalDemo(); //一个SingleTon实例
//模拟并发访问(第二个参数表示用户访问时输入的用户名)
VisitThread visitor1 = new VisitThread(demo, "Bruce"); //访问者1
VisitThread visitor2 = new VisitThread(demo, "Phil"); //访问者2
VisitThread visitor3 = new VisitThread(demo, "David"); //访问者3
visitor1.start();
visitor2.start();
visitor3.start();
}
/**
* 访问线程(一个线程代表一个并发时的不同用户访问)
*/
private static class VisitThread extends Thread {
private ThreadLocalDemo demo;
private String name;
public VisitThread(ThreadLocalDemo demo, String name) {
this.demo = demo;
this.name = name;
}
public void run() {
demo.setName(name);
String tempName = name; //tempName是线程安全的
//让程序暂停一秒,以便显示线程不安全而出现的错误
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread[" + this.currentThread().getName() + "] name[" + demo.getName() + "]" + " (should be[" + tempName + "])");
}
}
}
运行输出如下
Thread[Thread-0] name[David] (should be[Bruce])
Thread[Thread-2] name[David] (should be[David])
Thread[Thread-1] name[David] (should be[Phil])
问题:可以看到三个用户输入的名字都变成了"David"(demo.getName() = "David")
要解决以上问题,可以选择用synchronized同步,这样就影响了并发性能。
我们也可以选择一种不影响并发性能的解决方案。把①的注释放开,getName() 和setName()换成②和③,这样好能解决并发问题。
再次运行输出如下
Thread[Thread-2] name[David] (should be[David])
Thread[Thread-1] name[Phil] (should be[Phil])
Thread[Thread-0] name[Bruce] (should be[Bruce])
以上主要是举个并发问题的例子,如果想更了解ThreadLocal,可以看下面的文章
http://www.builder.com.cn/2007/0529/404695.shtml