/**
* 这样的map属于全局级别的,会冲突,而且这样的实现方法好像是1.3以前的方法
* @author Han
*/
public class MyThreadLocalDemo {
private static Map<Thread,String> map = new HashMap<Thread,String>();
private static String contextStr = "";
public static void set(String str){
//System.out.println(map.containsKey(Thread.currentThread()));
map.put(Thread.currentThread(), str);
}
public static String get(){
System.out.println(map.keySet());
return map.get(Thread.currentThread());
}
public static String getStr(){
return contextStr;
}
public static void setStr(String str){
contextStr = str;
}
public static void print(){
System.out.println(map);
}
public class MyThread extends Thread{
// public MyThread(String name){
// super(name);
// }
@Override
public void run() {
int i = new Random().nextInt(10);
String str = Thread.currentThread().getId()+","+i;
MyThreadLocalDemo.set(str);
MyThreadLocalDemo.setStr(str);
System.out.println("```threadlocal的值"+str);
System.out.println("```string的值"+str);
//System.out.println(Thread.currentThread());
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("`threadlocal的值"+MyThreadLocalDemo.get());
System.out.println("`String的值"+MyThreadLocalDemo.getStr());
//print();
}
}
public static void main(String[] args) {
//运行以下代码可以看出,两个线程,持有的threadlocal没有因为另一个改变了值而发生改变
// for(int i = 0;i<20;i++){
// Thread t1 = new MyThreadLocalDemo().new MyThread();
// Thread t2 = new MyThreadLocalDemo().new MyThread();
// t1.start();
// t2.start();
// }
Thread t1 = new MyThreadLocalDemo().new MyThread();
Thread t2 = new MyThreadLocalDemo().new MyThread();
t1.start();
t2.start();
}
}
这个程序的执行结果,有时候会get 出来 null,有时候不会。没想明白。ThreadLocal是为每个Thread对象都会一个独自的ThreadMap,不考虑性能的话,我觉得用map也是一样的效果。
但是实在不知道哪里出了问题,求大神指教。
几点错误
1、MyThreadLocalDemo.setStr(str); 这个无意义,因为contextStr 是静态变量,肯定是最后一个更新的值,不是每个线程的值
2、出现null的原因是 map.put(Thread.currentThread(), str);这句话,因为多个线程,hashmap不是现场安全的,可能两个线程同时添加到同一个节点上,有一个线程的节点被覆盖了。值也就不存在了。
解决方式
public static void set(String str){
//System.out.println(map.containsKey(Thread.currentThread()));
map.put(Thread.currentThread(), str);
}
改成
public static synchronized void set(String str){
//System.out.println(map.containsKey(Thread.currentThread()));
map.put(Thread.currentThread(), str);
}
或者你也为每个thread增加map。每个线程单独对象就不存在被覆盖的情况。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。