很久之前就知道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