Android多线程之ThreadLocal
2016-07-06 00:11
417 查看
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=null I/threadloacl: thread_one======1 I/threadloacl: thread_two======2
这里在主线程中并没有赋值,所以主线程中的值为null。这就是关于ThreadLocal的我的浅显的理解,希望对看到这篇文章的人能有所增益,同时这也是方便我自己理解,加强记忆,如有纰漏之处还望指正!
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories