ThreadLocal是什么东东呢
ThreadLocal = “Thread” 的“Local”信息 ,是一个线程独有信息保存的类。
1、通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。 2、而使用ThreadLocal创建的变量只能被当前线程访问,其他线程则无法访问和修改。
怎么做到的呢
往ThreadLocal 里面塞数据
threadlocal.set(value)
->>
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
我们看到是从这里获取的map:ThreadLocalMap
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
这里创建的ThreadLocalMap
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
ThreadLocalMap作为Thead的成员变量
class Thread implements Runnable {
/* ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
}
所以最终看到了这里,就明白了,原来同一个线程中通过ThreadLocal设置的信息都保存到了当前线程的Map中,引用关系是这样的ThreadLocal-》ThreadLocalMap-》Thread 那么ThreadLocalMap作为一个线程的变量,根据每个线程的栈的变量是隔离的,所以这样就回到了文章最前面的ThreadLocal只能访问和修改当前线程的信息。
但是,Map会不会内存泄露呢,不及时清理怎么办?
看代码吧~
static class ThreadLocalMap {
/** * The entries in this hash map extend WeakReference, using * its main ref field as the key (which is always a * ThreadLocal object). Note that null keys (i.e. entry.get() * == null) mean that the key is no longer referenced, so the * entry can be expunged from table. Such entries are referred to * as "stale entries" in the code that follows. */
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
}
这里是一个弱引用,所以没事情啦!该释放就自然释放了!
但是我们有办法在父子线程之间传递信息么
答案是可以的
final ThreadLocal threadLocal = new InheritableThreadLocal(); threadLocal.set("google.com");
Thread t = new Thread() {
@Override public void run() {
super.run();
Log.i("test", "InheritableThreadLocal =" + threadLocal.get());
}
};
t.start();
//Thread.java
private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc) {
//code goes here
if (parent.inheritableThreadLocals != null)
this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize;
/* Set thread ID */
tid = nextThreadID();
}
但是Android开发中,遇到的很少了就。