Looper中ThreadLocal的简介

Android  2018年5月13日 pm7:29发布7年前 (2018)更新 91es.com站长
58 0 0

一 ThreadLocal的简介

This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its {@code get} or {@code set} method) has its own, independently initialized copy of the variable. {@code ThreadLocal} instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).

以上是摘抄于java中的ThreadLocal.java中的解释.

概意有如下几点(英文不是很好,抱歉)

  1. ThreadLocal这个类提供线程本地变量
  2. 每个线程可以通过get()或者set()得到或设置自己拥有的变量,且不相互映像

我们通过实例简单测试一下:

        //private ThreadLocal<String> mThreadLocal = new ThreadLocal<>();
        mThreadLocal.set(Thread.currentThread().getName()); //保存当前主线程的名字
        Log.d(TAG, "----Thread#main------mThreadLocal.get():" + mThreadLocal.get());

        new Thread("Thread#1") {
            @Override
            public void run() {
                super.run();
                //保存线程1中的名字
                mThreadLocal.set(Thread.currentThread().getName());
                Log.d(TAG, "----Thread#1------mThreadLocal.get():" + mThreadLocal.get());
            }
        }.start();

        new Thread("Thread#2") {
            @Override
            public void run() {
                super.run();
                //保存线程2中的名字
                mThreadLocal.set(Thread.currentThread().getName());
                Log.d(TAG, "----Thread#2------mThreadLocal.get():" + mThreadLocal.get());
            }
        }.start();

以下就是输出的日志

----Thread#main------mThreadLocal.get():main
----Thread#1------mThreadLocal.get():Thread#1
----Thread#2------mThreadLocal.get():Thread#2

从日志中可以看出(1)ThreadLocal中保存的都是每个线程中的局部变量,而且每个线程只能改变自己线程中的值.

ThreadLocal中部分方法的简介
  1. get() 获取当前线程保存的局部变量
  2. set() 设置当前线程的变量值
  3. remove() //移除当前变量的值
  4. setInitialValue()  私有的,设置初始化值

我们平时常用的也就get(),set()和remove()


    public T get() {
        Thread t = Thread.currentThread();
        //获取当前线程中ThreadLocalMap变量,ThreadLocalMap是ThreadLocal中定义的类
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        //如果map为空,就初始化map
        return setInitialValue();
    }

    private T setInitialValue() {
        T value = initialValue(); // 返回 null
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
        return 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);
    }


     public void remove() {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if (m != null)
             m.remove(this);
     }

 

二 ThreadLocal在Looper的作用

而我们在(Android消息机制Handler,Looper,Message,MessageQueue关系之一)提到过,base\core\java\android\os\Looper.java中出现了ThreadLocal

    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();

     //主线程中获取Looper

    public static Looper getMainLooper() {
        synchronized (Looper.class) {
            //在prepareMainLooper中初始化的
            //因为一个应用只有一个主线,所以不用动态的获取
            return sMainLooper;
        }
    }

    public static void prepareMainLooper() {
        prepare(false);//这里初始化并保存当前线程的Looper对象
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper(); //这里获取的主线程中的Looper
        }
    }

//最终都是调用sThreadLocal.get方法获取
 public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }

ThreadLocal中存储的是Looper,而且每个线程中只能有一个Looper

所以我们可通过线程来获取当前线程中的Looper

 历史上的今天

  1. 2024: Android刷新媒体库的方法(0条评论)
  2. 2024: AudioTrack简单使用(1条评论)
  3. 2023: Android截图命令介绍(0条评论)
  4. 2022: 视频播放中,拖动进度条可以seek到相应视频帧(0条评论)
  5. 2021: Android应用启动时出现白屏或者黑屏问题的简介(0条评论)
版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站内容: 部分来源于网络,仅供学习和参考,若侵权请留言
3、 本站申明: 个人流水账日记,内容并不保证有效

暂无评论

暂无评论...

随机推荐

Android刷新媒体库的方法

前言记录一下Android中如何通知扫描文件,也就是把新创建的媒体文件添加到MediaProvider中。这里简单介绍一下个人常用的几种方式。正文方式一发送广播,Intent.ACTION_MEDIA_SCANNER_SCAN_FILE是Android定义的广播。private voi...

Thread中断简单介绍

前言简答记录一下Thread中断相关的内容。记录一下,方便自己查阅。正文Thread中断主要涉及如下几个方法:interrupt()isInterrupted()interrupted()下面单独介绍一下。interrupt()interrupt()使线程中断。...

USB挂载查看状态简单记录

前言简单的记录一下Android中查看U盘挂载信息。不一定对,只是个人的流水笔记。正文插入U盘,连接Android设备,打开cmd,输入adb shell,然后执行对应命令即可。blkid 信息blkid命令定位/打印块设备属性//部分/dev/block/mmcblk0p24: ...

朱自清:正义

正义是在我们心理!从明哲的教训和见闻的意义中,我们不是得着大批的正义么?但白白的搁在心里,谁也不去取用,却至少是可惜的事。两石白米搁在屋里,总要吃它干净,两箱衣服堆在屋里,总要轮流穿换,一大堆正义却扔在一旁,满不理会,我们真大方,真舍得!看来正义这东西也真*,竟抵不上白米的一个尖儿,衣服的一个扣儿。...

博尔赫斯:我用什么才能留住你

我用什么才能留住你?我给你瘦落的街道、绝望的落日、荒郊的月亮。我给你一个久久地望着孤月的人的悲哀。 我给你我已死去的祖辈,后人们用大理石祭奠的先魂:我父亲的父亲,阵亡于布宜诺斯艾利斯的边境,两颗子弹射穿了他的胸膛,死的时候蓄着胡子,尸体被士兵们用牛皮裹起; ...

Glide V4和V3 使用不同

Glide是目前 Android 上最流行的图片加载库之一。目前Glide已经更新到了4.11.0repositories { mavenCentral() google()}dependencies { implementation 'com.github.bumptech...