Java多线程之----ThreadLocal

来源:互联网 发布:淘宝退款率行业水平 编辑:程序博客网 时间:2024/04/30 05:48
    有时候,我们需要在每个线程中有一个其他线程不能访问的变量,起到保护作用,但是下面这种情况下,该线程中的变量被共享了

public class ThreadLocalTest {public static void main(String[] args) {ThreadLocalTask task = new ThreadLocalTask();for (int i = 0; i < 10; i++) {new Thread(task).start();}}}class ThreadLocalTask implements Runnable {private int a = 0;@Overridepublic void run() {a++;System.out.println(Thread.currentThread().getName() + ": a = " + a);}}//输出结果如下//Thread-1: a = 1//Thread-3: a = 2//Thread-5: a = 3//Thread-7: a = 4//Thread-9: a = 5//Thread-0: a = 6//Thread-2: a = 7//Thread-4: a = 8//Thread-6: a = 9//Thread-8: a = 10</span>
    可以看到,当传入同一个任务类时,不同线程访问的a是同一个,那么需要做隔离

    ThreadLocal类可以提供这个功能,下面改写一下上面的类

public class ThreadLocalTest {public static void main(String[] args) {ThreadLocalTask task = new ThreadLocalTask();for (int i = 0; i < 10; i++) {new Thread(task).start();}}}class ThreadLocalTask implements Runnable {private ThreadLocal<Integer> a = new ThreadLocal<Integer>() {protected Integer initialValue() {return 0;};};@Overridepublic void run() {a.set(a.get() + 1);System.out.println(Thread.currentThread().getName() + ": a = " + a.get());}}//输出结果如下//Thread-1: a = 1//Thread-3: a = 1//Thread-5: a = 1//Thread-7: a = 1//Thread-9: a = 1//Thread-0: a = 1//Thread-2: a = 1//Thread-4: a = 1//Thread-6: a = 1//Thread-8: a = 1

    通过ThreadLocal的get和set方法来设置值和获取值,另外在声明的时候,可以重写它的init方法,来设置初始化值  

    这样,多个线程之间就互不干扰了

    实际中使用的肯定不是简单的一个int变量,可能是其他复杂的东西,不过核心是不变的,这里只使用一个简单的小例子来介绍基本用法

    那么,源码里面是如何实现的呢? 其实很简单,每一个线程都有一个map来存放这个值,取的时候就从这里取出来,让我们看看set方法

    public void set(T value) {        Thread t = Thread.currentThread();        ThreadLocalMap map = getMap(t);// 获取map        if (map != null)            map.set(this, value);// 以当前对象作为key,放到map里        else            createMap(t, value);    }
    再看看getMap和createMap方法
    ThreadLocalMap getMap(Thread t) {        return t.threadLocals;    }    void createMap(Thread t, T firstValue) {        t.threadLocals = new ThreadLocalMap(this, firstValue);    }
    getMap方法就是直接返回这个线程对象中的map,createMap方法就是为线程对象中的map初始化,这样,每个线程(对象)就有自己的map,从而两个线程(对象)之间的数据就被隔离了
    
    最后就写到这里,如果有学到新的,会继续更新....

    推荐几篇文章

    http://lavasoft.blog.51cto.com/62575/51926/

    http://blog.csdn.net/lufeng20/article/details/24314381

    http://www.iteye.com/topic/103804

    






0 0
原创粉丝点击