关于一个全局map实现ThreadLocal遇到的错误-问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文

关于一个全局map实现ThreadLocal遇到的错误

2016-03-13 14:17:12 1921 1
/**
 * 这样的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)
  • 蛮大人123
    2019-07-17 19:02:32

    几点错误
    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。每个线程单独对象就不存在被覆盖的情况。

    0 0
相关问答

0

回答

大佬们有没有遇到过这种情况?就是我们用FlinkSQL实时计算订单数据,有时候出现一个订单两个子单的

2022-06-30 11:06:22 76浏览量 回答数 0

1

回答

如何设计和编码实现一个具备 LRU 过期策略的缓存程序?

2021-12-23 14:38:20 133浏览量 回答数 1

1

回答

flink1.12.4 写入hdfs报错 java.lang.OutOfMemoryError: D

2021-12-08 09:42:04 337浏览量 回答数 1

0

回答

java中ThreadPool相关的学习方法

2021-10-26 13:03:00 206浏览量 回答数 0

1

回答

ThreadLocal是如何做到为每一个线程维护一份独立的变量副本的呢?

2021-10-27 16:32:23 131浏览量 回答数 1

1

回答

Java的ThreadLocal 无法解决共享对象的更新问题时该如何处理?

2021-10-13 14:02:10 455浏览量 回答数 1

1

回答

[@徐雷frank][¥20]关于ThreadLocal的内存泄漏

2018-11-13 14:47:56 1410浏览量 回答数 1

0

回答

ICA联盟会员服务与权益发布

2018-07-30 23:19:13 790浏览量 回答数 0

1

回答

一个页面布局方面遇到的问题,想请教各位高手该如何实现

2016-05-27 13:58:16 1347浏览量 回答数 1

1

回答

上传OSS遇到如下返回错误:ErrorEISDIRreaderrno28codeEISDIR

2014-12-03 11:06:37 5287浏览量 回答数 1
+关注
蛮大人123
我说我不帅他们就打我,还说我虚伪
0
文章
7733
问答
问答排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载