关于ThreadLocal

来源:互联网 发布:中文域名怎么访问 编辑:程序博客网 时间:2024/05/16 08:26

很久之前就知道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@d0970fd06-08 13:10:48.190 9997-9997/? I/ThreadlocalTest: thread name is main and val is =1006-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@d0970fd06-08 13:10:48.192 9997-10035/? I/ThreadlocalTest: thread name is Thread-167 and val is =null06-08 13:10:48.192 9997-10035/? I/ThreadlocalTest: then set val ,thread name is Thread-167 and val is =2006-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

原创粉丝点击