Android线程管理(二):ThreadLocal

ThreadLocal并非是一个线程的本地实现版本,首先它并不是一个Thread,而是 threadLocalvariable(线程局部变量),简单的理解就是:为每一个使用该变量的线程提供变量值的副本,是JAVA中一种特殊的线程绑定机制。

1:从线程的角度来看:每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal实例时可访问的,那么在线程消失之后,其线程局部实例的所有副本都会被垃圾回收器回收

2:通过ThreadLocal存取数据,总是与当前线程相关,也就是说,JVM为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境出现的并发问题提供了一种隔离机制,它采用空间换时间的方式,来保证同时访问而不受影响。

3:ThreadLocal实现版

public class SimpleThreadLocal{
        private Map valueMap = Collections.synchronizedMap(new HashMap());
        /**
         * 设置副本的值
         * */
        public void set(Object newValue) {
            //①键为线程对象,值为本线程的变量副本
            valueMap.put(Thread.currentThread(), newValue);
        }
        /**
         *  获取副本的值
         * */
        public Object get() {
            Thread currentThread = Thread.currentThread();
            //②返回本线程对应的变量
            Object o = valueMap.get(currentThread);
            //③如果在Map中不存在,放到Map中保存起来。
            if (o == null && !valueMap.containsKey(currentThread)) {
                o = initialValue();
                valueMap.put(currentThread, o);
            }
            return o;
        }
        /**
         * 移除副本的值
         * */
        public void remove() {
            valueMap.remove(Thread.currentThread());
        }
        /**
         *
         * */
        public Object initialValue() {
            return null;
        }
}

4: ThreadLocal与同步机制有什么优势了?

在同步机制中,通过对象锁的机制,保证同一时间只有一个线程访问变量,这时该变量时多个线程共享的,那么使用同步机制需要程序缜密的分析,什么时候需要对变量进行读写,什么时候需要锁定对象,什么时候释放对象等繁杂问题,那么这会使程序的编写难度变大。

而ThreadLocal从另一个角度解决多线程的并发访问,因为ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突,因为每个线程都拥有自己的独立变量,所以就没有必要对该变量进行同步,所以在编写程序时,应该把不安全的变量封装进 ThreadLocal.

5: ThreadLocal实际使用

在Android Handler消息机制中,Looper.prepare() 就是通过ThreadLocal机制 将 当前线程和 Looper绑定。

在访问数据库时,建立数据库连接对象,就可以通过ThreadLocal将连接对象和线程绑定

在访问web服务器时,客户端和服务端生成Session 。也可以通过 ThreadLocal将Session和线程绑定

上一篇:Java线程优先级


下一篇:模拟死锁