关于ThreadLocal

很久之前就知道Threadlocal 这个东西,但没有仔细研究过源码,也没有在项目中使用过。今天准备研究下一,先来个小例子,看看Threadlocal有什么用。

package com.example.bxh.sayhello.sometest;

import android.util.Log;

/**
 * Created by bxh on 6/8/17.
 */

public class ThreadlocalTest {
    private static final String TAG = "ThreadlocalTest";
    ThreadlocalTestIner mThreadlocalTestIner;

    public ThreadlocalTest() {
        this.mThreadlocalTestIner = new ThreadlocalTestIner();
    }

    public void test() {
        Log.i(TAG, "thread name is "+Thread.currentThread().getName()+" and tl  is " + mThreadlocalTestIner.getIntThreadLocal());
        Log.i(TAG, "thread name is "+Thread.currentThread().getName()+" and val is ="+ mThreadlocalTestIner.getIntThreadLocalVal());
        MyThread m = new MyThread(mThreadlocalTestIner);
        m.start();
        try {
            m.join();
        }catch (InterruptedException e){
            Log.i(TAG, "InterruptedException is "+e.getMessage());
        }
        Log.i(TAG, "thread name is "+Thread.currentThread().getName()+" and val is ="+ mThreadlocalTestIner.getIntThreadLocalVal());

    }

    class ThreadlocalTestIner {
        public ThreadLocal<Integer> getIntThreadLocal() {
            return intThreadLocal;
        }

        private ThreadLocal<Integer> intThreadLocal = new ThreadLocal<Integer>() {
            @Override
            protected Integer initialValue() {
                return super.initialValue();
            }

            @Override
            public Integer get() {
                return super.get();
            }

            @Override
            public void set(Integer value) {
                super.set(value);
            }

            @Override
            public void remove() {
                super.remove();
            }
        };

        public ThreadlocalTestIner() {
            setIntThreadLocal(10);
        }

        public ThreadlocalTestIner(ThreadLocal<Integer> intThreadLocal) {
            this.intThreadLocal = intThreadLocal;
        }

        public void setIntThreadLocal(int val) {
            this.intThreadLocal.set(val);
        }

        public Integer getIntThreadLocalVal() {
            return intThreadLocal.get();
        }
    }

    class MyThread extends Thread {
        ThreadlocalTestIner iner;
        public MyThread(ThreadlocalTestIner i) {
          this.iner = i;
        }

        @Override
        public void run() {
            Log.i(TAG, "thread name is "+Thread.currentThread().getName()+" and tl is " + iner.getIntThreadLocal());
            Log.i(TAG, "thread name is "+Thread.currentThread().getName()+" and val is ="+ mThreadlocalTestIner.getIntThreadLocalVal());
            iner.setIntThreadLocal(20);


            Log.i(TAG, "then set val ,thread name is "+Thread.currentThread().getName()+" and val is ="+ mThreadlocalTestIner.getIntThreadLocalVal());
        }
    }
}

执行test方法后,打印出的log如下所示:

06-08 13:10:48.190 9997-9997/? I/ThreadlocalTest: thread name is main and tl  is com.example.bxh.sayhello.sometest.ThreadlocalTest$ThreadlocalTestIner$1@d0970fd
06-08 13:10:48.190 9997-9997/? I/ThreadlocalTest: thread name is main and val is =10
06-08 13:10:48.191 9997-10035/? I/ThreadlocalTest: thread name is Thread-167 and tl is com.example.bxh.sayhello.sometest.ThreadlocalTest$ThreadlocalTestIner$1@d0970fd
06-08 13:10:48.192 9997-10035/? I/ThreadlocalTest: thread name is Thread-167 and val is =null
06-08 13:10:48.192 9997-10035/? I/ThreadlocalTest: then set val ,thread name is Thread-167 and val is =20
06-08 13:10:48.192 9997-9997/? I/ThreadlocalTest: thread name is main and val is =10

通过log得知,子线程中的Threadlocal与主线程的Threadlocal 是同一个对象,但是get到的值却不同,似乎子线程对值得修改,不影响主线程的值,有猫腻……
事实上,Threadlocal的特性就是线程之间互不影响。每个线程有自己的数据备份,在A线程中修改仅仅影响A中数据,对B线程没有影响,B中原来是什么值,还是什么值。

……需要阅读源码了……
详见我的笔记
https://www.evernote.com/l/AUvWQwFU8s9LZo0F_fpmCoiVHYsgOPa70KY

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值