Android多线程之ThreadLocal

来源:互联网 发布:mac下常用软件 编辑:程序博客网 时间:2024/06/10 15:26

ThreadLocal简介

ThreadLocal实现的是线程的数据的本地存储,同一个ThreadLocal对象在不同的线程中都有自己的值,所有的线程共享同一个ThreadLocal对象,但是每一个访问它的线程都存储这个线程自己的值,并且一个线程改变了这个ThreadLocal对象的值但是并不能改变其他线程中ThreadLocal的值。ThreadLocal允许赋值为null。

ThreadLocal的主要方法

ThreadLocal的主要方法有set()方法,顾名思义,是对ThreadLocal进行赋值,get()方法则是取出当前线程中ThreadLocal的值,记住每一个线程中取出的值只是当前线程中之前所赋值。我们可以看一下ThreadLocal中的源码:

    public void set(T value) {        Thread currentThread = Thread.currentThread();        Values values = values(currentThread);        if (values == null) {            values = initializeValues(currentThread);        }        values.put(this, value);    }

上述源码中我们可以看到set()方法所存储的值存放在了Values中,这个values是什么呢?我们可以接着看下一段源码:

 static class Values {        private static final int INITIAL_SIZE = 16;        private static final Object TOMBSTONE = new Object();        private Object[] table;        private int mask;        private int size;        private int tombstones;        private int maximumLoad;        private int clean;        Values() {            initializeTable(INITIAL_SIZE);            this.size = 0;            this.tombstones = 0;        }        Values(Values fromParent) {            this.table = fromParent.table.clone();            this.mask = fromParent.mask;            this.size = fromParent.size;            this.tombstones = fromParent.tombstones;            this.maximumLoad = fromParent.maximumLoad;            this.clean = fromParent.clean;            inheritValues(fromParent);        }        @SuppressWarnings({"unchecked"})        private void inheritValues(Values fromParent) {            Object[] table = this.table;            for (int i = table.length - 2; i >= 0; i -= 2) {                Object k = table[i];                if (k == null || k == TOMBSTONE) {                    continue;                }tombstones and references.                Reference<InheritableThreadLocal<?>> reference                        = (Reference<InheritableThreadLocal<?>>) k;            Object below.                InheritableThreadLocal key = reference.get();                if (key != null) {                    table[i + 1] = key.childValue(fromParent.table[i + 1]);                } else {                    // The key was reclaimed.                    table[i] = TOMBSTONE;                    table[i + 1] = null;                    fromParent.table[i] = TOMBSTONE;                    fromParent.table[i + 1] = null;                    tombstones++;                    fromParent.tombstones++;                    size--;                    fromParent.size--;                }            }        }

我们可以看到这个values是个静态内部类,其中的inheritValues方法我们可以看到我们存储的值实际上都是存放在了Object数组里。而get()方法我们可以看一下:

public T get() {        // Optimized for the fast path.        Thread currentThread = Thread.currentThread();        Values values = values(currentThread);        if (values != null) {            Object[] table = values.table;            int index = hash & values.mask;            if (this.reference == table[index]) {                return (T) table[index + 1];            }        } else {            values = initializeValues(currentThread);        }        return (T) values.getAfterMiss(this);    }

源码中的描述很清晰,我们的值所在object数组中的索引实际就是index+1。还有remove()方法,这里remove()方法就不做详加解释,相信大家看名字亦能理解。

ThreadLocal的一个实现示例

这里写一个小的例子,帮助大家理解一下ThreadLocal:

  mFutureTest = new FutureTest();        mFutureTest.test();        mThreadLocal = new ThreadLocal<Integer>();        new Thread("thread_one"){            @Override            public void run() {                mThreadLocal.set(1);                Log.i("threadloacl","thread_one======"+mThreadLocal.get());            }        }.start();        new Thread("thread_two"){            @Override            public void run() {                mThreadLocal.set(2);                Log.i("threadloacl","thread_two======"+mThreadLocal.get());            }        }.start();        Log.i("threadlocal","mainthread="+mThreadLocal.get());

运行结果:

I/threadlocal: mainthread=nullI/threadloacl: thread_one======1I/threadloacl: thread_two======2

这里在主线程中并没有赋值,所以主线程中的值为null。这就是关于ThreadLocal的我的浅显的理解,希望对看到这篇文章的人能有所增益,同时这也是方便我自己理解,加强记忆,如有纰漏之处还望指正!

1 0
原创粉丝点击