zoukankan      html  css  js  c++  java
  • threadlocal彻底理解

    如果你定义了一个单实例的java bean,它有若干属性,但是有一个属性不是线程安全的,比如说HashMap。并且碰巧你并不需要在不同的线程中共享这个属性,也就是说这个属性不存在跨线程的意义。那么你不要sychronize这么复杂的东西,ThreadLocal将是你不错的选择。

    举例来说:

    复制代码
    import java.util.HashMap;
    
    public class TreadLocalTest {
    
        static ThreadLocal<HashMap> map0 = new ThreadLocal<HashMap>(){ 
            @Override 
            protected HashMap initialValue() { 
                System.out.println(Thread.currentThread().getName()+"initialValue"); 
                return new HashMap(); 
            } 
        }; 
        public void run(){ 
            Thread[] runs = new Thread[3]; 
            for(int i=0;i<runs.length;i++){ 
                runs[i]=new Thread(new T1(i)); 
            } 
            for(int i=0;i<runs.length;i++){ 
                runs[i].start(); 
            } 
        } 
        public static class T1 implements Runnable{ 
            int id; 
            public T1(int id0){ 
                id = id0; 
            } 
            public void run() { 
                System.out.println(Thread.currentThread().getName()+":start"); 
                HashMap map = map0.get(); 
                for(int i=0;i<10;i++){ 
                    map.put(i, i+id*100); 
                    try{ 
                        Thread.sleep(100); 
                    }catch(Exception ex){ 
                    } 
                } 
                System.out.println(Thread.currentThread().getName()+':'+map); 
            } 
        } 
        /** 
         * Main 
         * @param args 
         */ 
        public static void main(String[] args){ 
            TreadLocalTest test = new TreadLocalTest(); 
            test.run(); 
        }
    
    }
    复制代码

    输出解释;

    Thread-1:start 
    Thread-2:start 
    Thread-0:start 
    Thread-2initialValue 
    Thread-1initialValue 
    Thread-0initialValue 
    Thread-1:{0=100, 1=101, 2=102, 3=103, 4=104, 5=105, 6=106, 7=107, 8=108, 9=109} 
    Thread-2:{0=200, 1=201, 2=202, 3=203, 4=204, 5=205, 6=206, 7=207, 8=208, 9=209} 
    Thread-0:{0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9}

    可以看到map0 虽然是个静态变量,但是initialValue被调用了三次,通过debug发现,initialValue是从map0.get处发起的。而且每个线程都有自己的map,虽然他们同时执行。

    可以看到map0 虽然是个静态变量,但是initialValue被调用了三次,通过debug发现,initialValue是从map0.get处发起的。而且每个线程都有自己的map,虽然他们同时执行。

    可以看到map0 虽然是个静态变量,但是initialValue被调用了三次,通过debug发现,initialValue是从map0.get处发起的。而且每个线程都有自己的map,虽然他们同时执行。

    进入Theadlocal代码,可以发现如下的片段;

    复制代码
    public T get() { 
            Thread t = Thread.currentThread(); 
            ThreadLocalMap map = getMap(t); 
            if (map != null) { 
                ThreadLocalMap.Entry e = map.getEntry(this); 
                if (e != null) 
                    return (T)e.value; 
            } 
            return setInitialValue(); 
        }
    复制代码

    这说明ThreadLocal确实只有一个变量,但是它内部包含一个map,针对每个thread保留一个entry,如果对应的thread不存在则会调用initialValue。

  • 相关阅读:
    python的xpinyin模块:汉字转拼音
    中文报错SyntaxError: Non-UTF-8 code starting with 'xe6' in file
    "底层逻辑”是什么意思?
    【Golang】关于Go中logrus的用法
    【Golang】 关于Go语言中的锁
    【Golang】Go 通过结构(struct) 实现接口(interface)
    【Golang】Go语言之log的使用
    【Golang】Go中时间(time)的用法以及gorm处理时间戳
    【Golang】Go中三个点(...)用法
    一文彻底掌握Apache Hudi异步Clustering部署
  • 原文地址:https://www.cnblogs.com/panxuejun/p/8530587.html
Copyright © 2011-2022 走看看