郑州网站seo费用,开封市住房和城乡建设 网站,页面好看的教育类网站模板下载,市场营销策略的内容ThreadLocal翻译成中文比较准确的叫法应该是#xff1a;线程局部变量。 这个玩意有什么用处#xff0c;或者说为什么要有这么一个东东#xff1f;先解释一下#xff0c;在并发编程的时候#xff0c;成员变量如果不做任何处理其实是线程不安全的#xff0c;各个线程都 在操… ThreadLocal翻译成中文比较准确的叫法应该是线程局部变量。 这个玩意有什么用处或者说为什么要有这么一个东东先解释一下在并发编程的时候成员变量如果不做任何处理其实是线程不安全的各个线程都 在操作同一个变量显然是不行的并且我们也知道volatile这个关键字也是不能保证线程安全的。那么在有一种情况之下我们需要满足这样一个条件 变量是同一个但是每个线程都使用同一个初始值也就是使用同一个变量的一个新的副本。这种情况之下ThreadLocal就非常使用比如说DAO的数 据库连接我们知道DAO是单例的那么他的属性Connection就不是一个线程安全的变量。而我们每个线程都需要使用他并且各自使用各自的。这种 情况ThreadLocal就比较好的解决了这个问题。 我们从源码的角度来分析这个问题。 首先定义一个ThreadLocal 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class ConnectionUtil { private static ThreadLocalConnection tl new ThreadLocalConnection(); private static Connection initConn null; static { try { initConn DriverManager.getConnection(url, name and password); } catch (SQLException e) { e.printStackTrace(); } } public Connection getConn() { Connection c tl.get(); tl.set(initConn); return c; } } 这样子都是用同一个连接但是每个连接都是新的是同一个连接的副本。 那么实现机制是如何的呢 1、每个Thread对象内部都维护了一个ThreadLocalMap这样一个ThreadLocal的Map可以存放若干个ThreadLocal。 1 2 3 /* ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */ ThreadLocal.ThreadLocalMap threadLocals null; 2、当我们在调用get()方法的时候先获取当前线程然后获取到当前线程的ThreadLocalMap对象如果非空那么取出ThreadLocal的value否则进行初始化初始化就是将initialValue的值set到ThreadLocal中。 1 2 3 4 5 6 7 8 9 10 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(); } 3、当我们调用set()方法的时候很常规就是将值设置进ThreadLocal中。 4、总结当我们调用get方法的时候其实每个当前线程中都有一个ThreadLocal。每次获取或者设置都是对该ThreadLocal进行的操作是与其他线程分开的。 5、应用场景当很多线程需要多次使用同一个对象并且需要该对象具有相同初始化值的时候最适合使用ThreadLocal。 6、其实说再多也不如看一下源码来得清晰。如果要看源码其中涉及到一个WeakReference和一个Map这两个地方需要了解下这两 个东西分别是a.Java的弱引用也就是GC的时候会销毁该引用所包裹(引用)的对象这个threadLocal作为key可能被销毁但是只要我们 定义成他的类不卸载tl这个强引用就始终引用着这个ThreadLocal的永远不会被gc掉。b.和HashMap差不多。 事实上从本质来讲就是每个线程都维护了一个map而这个map的key就是threadLocal而值就是我们set的那个值每次线 程在get的时候都从自己的变量中取值既然从自己的变量中取值那肯定就不存在线程安全问题总体来讲ThreadLocal这个变量的状态根本没 有发生变化他仅仅是充当一个key的角色另外提供给每一个线程一个初始值。如果允许的话我们自己就能实现一个这样的功能只不过恰好JDK就已经帮 我们做了这个事情。 转载于:https://www.cnblogs.com/Berryxiong/p/6220545.html