Java——ThreadLocal类
来源:互联网 发布:六级仔细阅读技巧知乎 编辑:程序博客网 时间:2024/06/01 21:08
一,引入ThreadLocal
/*测试ThreadLocal对象 * ThreadLocal:这个类提供了一个线程本地的变量。 * 这些变量在被共享访问的情况下在不同的线程里是独立的 ( 必须通过 get 和 set 方法来访问 ) 。 * 很显然该类提供了一个机制可以防止多线程访问带来的不安全机制。实际上就是在线程本地保存一个变量, * 而不是通过共享变量。这个就要看我们的使用场合了,如果我们确实需要共享的数据,那还是必须通过同步机制来保证数据的安全。 * 如果有些情况希望不同的线程保存的变量各自分开,那用这个还是比较合适的。 ThreadLocal 这个类本身不是代表线程要访问的变量,这个类的成员变量才是。 JDK1.5 给 ThreadLocal 加了泛型功能,即是 ThreadLocal<T>, 这个泛型 T 即是要线程的本地变量。 线程通过 ThreadLocal 的 get 和 set 方法去访问这个变量 T 。 ThreadLocal 提供了一个机制, 它能保证线程通过这个来访问它来访问类型为 T 的变量的时候是不同的拷贝。所以访问该变量必须通过 Threadlocal 这个类只提供了两个 public 方法,即是 get() 和 set ()方法来访问。 同时还提供了一个 inintValue() 的 protected 方法。该方法用来初始化变量值。 注意 :默认情况下 initValue(), 返回 null 。线程在没有调用 set 之前,第一次调用 get 的时候, get 方法会默认去调用 initValue 这个方法。所以如果没有覆写这个方法,可能导致 get 返回的是 null 。 当然如果调用过 set 就不会有这种情况了。但是往往在多线程情况下我们不能保证每个线程的在调用 get 之前都调用了 set , 所以最好对 initValue 进行覆写,以免导致空指针异常。 * */
测试,在没有ThreadLocal的时候:
public class TestThreadLocal {public static int a = 0;public static void main(String[] args) {MyThread myThread=new MyThread();myThread.start();for(int i=0;i<5;i++){System.out.println(Thread.currentThread().getName()+":"+a);}}public static class MyThread extends Thread {public void run(){for(int i=0;i<5;i++){a=++a;System.out.println(Thread.currentThread().getName()+":"+a);}}}}
测试结果:
main:1main:2main:3main:4main:5Thread-0:6Thread-0:7Thread-0:8Thread-0:9Thread-0:10
发现结果很混乱,两个线程的执行明显有交叉。
使用ThreadLocal之后:
public class TestThreadLocal {//public static int a = 0;public static ThreadLocal<Integer> a=new ThreadLocal<Integer>(){public Integer initialValue(){//初始化a的值return 0;}};public static void main(String[] args) {MyThread myThread=new MyThread();myThread.start();for(int i=0;i<5;i++){//a=++a;a.set(a.get()+1);System.out.println(Thread.currentThread().getName()+":"+a.get());}}public static class MyThread extends Thread {public void run(){for(int i=0;i<5;i++){//a=++a;a.set(a.get()+1);System.out.println(Thread.currentThread().getName()+":"+a.get());}}}}
结果:
Thread-0:1Thread-0:2Thread-0:3Thread-0:4Thread-0:5main:1main:2main:3main:4main:5
使用了线程本地变量之后,我们必须通过get和set方法对变量进行读写。
二,简单介绍ThreadLocal
/** * Returns the current thread's "initial value" for this * thread-local variable. This method will be invoked the first * time a thread accesses the variable with the {@link #get} * method, unless the thread previously invoked the {@link #set} * method, in which case the <tt>initialValue</tt> method will not * be invoked for the thread. Normally, this method is invoked at * most once per thread, but it may be invoked again in case of * subsequent invocations of {@link #remove} followed by {@link #get}. * * <p>This implementation simply returns <tt>null</tt>; if the * programmer desires thread-local variables to have an initial * value other than <tt>null</tt>, <tt>ThreadLocal</tt> must be * subclassed, and this method overridden. Typically, an * anonymous inner class will be used. * * @return the initial value for this thread-local */ protected T initialValue() { return null; }
变量的初始化操作在这里完成,默认返回null,建议override此方法,确保get之前已进行过set操作,防止get的时候出错。
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类中,有一个内部静态 类ThreadLocalMap,在这里存放着以key为当前threadLocal的object。
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); }
set方法也是这样类似的,ThreadLocal里面通常放入的值通常就是采用这两种方法进行操作的,哦,还有remove:
public void remove() { ThreadLocalMap m = getMap(Thread.currentThread()); if (m != null) m.remove(this); }
好多代码のの。。。。大致先瞅瞅,然后接着切换回我们的spring源码解析,这篇只是小 插曲。
0 0
- Java——ThreadLocal类
- Java多线程——ThreadLocal类
- Java多线程——ThreadLocal
- java多线程——ThreadLocal
- Java并发编程—ThreadLocal
- java基础—Java里面的Threadlocal
- Java 多线程(九)——ThreadLocal类
- Java 多线程(九)——ThreadLocal类
- Java多线程——2 ThreadLocal
- java多线程之——ThreadLocal
- Java并发笔记五——ThreadLocal
- Java多线程(10)——ThreadLocal
- 【Java并发编程实践】— ThreadLocal分析
- 【Java并发编程实践】— ThreadLocal分析
- Java.lang.ThreadLocal类
- java的ThreadLocal类
- Java中的ThreadLocal类
- Java中的ThreadLocal类
- Swift 单例
- 学生信息管理系统-书本实例
- java实现几种常见的排序算法
- 初识JSON
- 解决Hibernate原生SQL映射问题
- Java——ThreadLocal类
- ioctl---字符设备的控制技术
- 广播的无序广播
- HDU5651(逆元)
- SqlHelper类(BY_韩顺平)
- 你必须了解的RecyclerView的五大开源项目-解决上拉加载、下拉刷新和添加Header、Footer等问题
- linux基本命令(16)——which命令
- poj2777 Count Color(成段更新)
- 共同学习Java源代码--数据结构--AbstractList抽象类(五)