Android开发——ThreadLocal功能介绍
2016-08-04 16:07
344 查看
1.使用场景以及作用介绍
(1)ThreadLocal适用于某些数据以线程为作用域并且不同线程具有不同数据副本的场景。
比如对于Handler来说,它需要获取当前线程的Looper,很显然Looper的作用域就是线程并且不同线程具有不同的Looper,这个时候通过ThreadLocal就可以轻松实现Looper在线程中的存取。
(2)ThreadLocal的另一个使用场景是复杂逻辑下的对象传递。
比如监听器的传递,有时一个线程中的任务过于复杂,又需要监听器贯穿整个线程的执行过程,这时就可以使用ThreadLocal,这样就可以让监听器作为线程内的全局对象而存在,在线程内部只要通过get方法就可以获取到监听器。每个监听器对象都在自己的线程内部存储。
如果不这样做,我们可能将监听器作为函数参数传递,但是这样会很麻烦,降低代码的可读性。或者我们会将监听器作为静态变量供线程访问,但是100个线程就需要100个静态的监听器对象,显然是无法接受的。
2. 使用实例
输出结果如下:
3. 原理介绍
不同的线程访问同一个ThreadLocal获取到的值是不一样的,这是因为,在set方法中,首先通过Thread.currentThread()获取当前线程,Thread类的内部有一个专门用于存储线程ThreadLocal数据的成员Value,通过下面方法获得。
set方法源码如下,get源码略。
总结:ThreadLocal的set和get操作,对象都是当前线程的Value类实例中的table数组,显然不同线程,数组不同,因此ThreadLocal可以在多线程中互不干扰地存储和修改数据。
(1)ThreadLocal适用于某些数据以线程为作用域并且不同线程具有不同数据副本的场景。
比如对于Handler来说,它需要获取当前线程的Looper,很显然Looper的作用域就是线程并且不同线程具有不同的Looper,这个时候通过ThreadLocal就可以轻松实现Looper在线程中的存取。
(2)ThreadLocal的另一个使用场景是复杂逻辑下的对象传递。
比如监听器的传递,有时一个线程中的任务过于复杂,又需要监听器贯穿整个线程的执行过程,这时就可以使用ThreadLocal,这样就可以让监听器作为线程内的全局对象而存在,在线程内部只要通过get方法就可以获取到监听器。每个监听器对象都在自己的线程内部存储。
如果不这样做,我们可能将监听器作为函数参数传递,但是这样会很麻烦,降低代码的可读性。或者我们会将监听器作为静态变量供线程访问,但是100个线程就需要100个静态的监听器对象,显然是无法接受的。
2. 使用实例
//首先定义一个ThreadLocal对象,选择泛型为Boolean类型 private ThreadLocal<Boolean> mThreadLocal = new ThreadLocal<Boolean>(); //在主线程、子线程1、子线程2中去设置访问它的值 mThreadLocal.set(true); System.out.println("Main " + mThreadLocal.get()); new Thread("Thread#1"){ @Override public void run() { mThreadLocal.set(false); System.out.println("Thread#1 " + mThreadLocal.get()); } }.start(); new Thread("Thread#2"){ @Override public void run() { System.out.println("Thread#2 " + mThreadLocal.get()); } }.start();
输出结果如下:
Main true Thread#1 false Thread#2 null
3. 原理介绍
不同的线程访问同一个ThreadLocal获取到的值是不一样的,这是因为,在set方法中,首先通过Thread.currentThread()获取当前线程,Thread类的内部有一个专门用于存储线程ThreadLocal数据的成员Value,通过下面方法获得。
Value value = values(Thread.currentThread());拿到value后,value对象内部有一个数组:private Object[]table,ThreadLocal的值就存在这个table中,最后通过value的put方法,将最初set方法传递进来的值,根据一定的算法放入table数组中。取数据则通过get方法,依据算法的逆来获取。
set方法源码如下,get源码略。
public void set(T value){ Thread currentThread = Thread.currentThread(); Value values = values(currentThread); if(values == null){ //初始化操作 values = initializeValues(currentThread); } values.put(this,value); }
总结:ThreadLocal的set和get操作,对象都是当前线程的Value类实例中的table数组,显然不同线程,数组不同,因此ThreadLocal可以在多线程中互不干扰地存储和修改数据。
相关文章推荐
- Android开发——ThreadLocal功能介绍
- Android开发自学笔记—1.1(番外)AndroidStudio常用功能介绍
- Android开发,MapBox地图详细介绍、使用、部分功能实现(初始化、标记、定位、styleurl)
- [置顶]Android 项目开发 基于Web Service 服务的中英翻译软件(一)功能介绍
- android安卓客户端260X心里健康频道的开发过程和原理之一。。产品功能介绍
- Android系统防火墙开发一(1)功能介绍
- Android开发自学笔记—1.1(番外)AndroidStudio常用功能介绍
- 一起来开发Android的天气软件(一)——功能规格介绍
- Android开发的测试功能的开发文档学习--介绍
- Android 项目开发 基于Web Service 服务的中英翻译软件(一)功能介绍
- Android浏览器插件开发(三)——ANPInterface的介绍
- Android的电话功能介绍
- Android的电话功能介绍
- Android的电话功能介绍
- Android开发框架介绍
- android开发中倒计时功能的实现
- 简单介绍如何应用DDMS协助开发Android Apps
- Android的电话功能介绍
- Android开发笔记3----Android Dalvik,包和文件介绍
- 简单介绍如何应用DDMS协助开发Android Apps