美文网首页
判断线程以及looper相关

判断线程以及looper相关

作者: 陈文超happylion | 来源:发表于2017-11-03 19:51 被阅读85次

    该文主要用于自我总结,提炼。语句未经斟酌,存在冗余重复等情况。各人客官可移步个人主页右下方的《原创技术博客》文集,里面是对外发布的一些技术博客。(咳咳,如果用的是移动设备,简书好像还没支持,只能自己找。。)
    当然也可继续阅读,如若有些地方生涩难懂。那。。那就给我发私信,我整理一下。( ●▽● )

    判断所在的线程是不是主线程

    可以使用

      if (Looper.getMainLooper()==Looper.myLooper()){
                //是主线程
            }else {
                //不是主线程
            }
    

    这里的Looper.getMainLooper()得到的就是主线程的Looper实例。这没有什么好说的。因为主线程的Looper在UI线程创建的时候(app启动的时候)就调用了

    Looper.prepare();//初始化Looper对象
    Looper.loop();//启动Looper
    

    所以说,主线程的looper实例肯定是有的,并且已经运行了。
    那么工作线程(异步线程)呢?不好意思,异步线程初始化时并没有绑定一个looper实例:

    Threads by default do not have a message loop associated with them. Of course, the method works

    所以如果一个工作线程没有绑定looper,那么Looper.myLooper()返回的结果将是null。如果想绑定一个looper线程,并让它运行,就需要:

    new Thread(new Runnable() {
                @Override
                public void run() {
                    Looper.prepare();//初始化Looper对象
                    Looper.loop();//启动Looper
                    //做一些线程的其他逻辑
                }
            }).start();
    

    我们看到上面Looper.myLooper(); Looper.prepare();Looper.loop();Looper的静态方法中并没有传入指定线程,但是最终得到的就是所在线程的looper或操作所在线程的looper。这是怎么做到的呢?
    这是因为在Looper内部维护了一个ThreadLocal:

    public class Looper {
     
        static final ThreadLocal<looper> sThreadLocal = new ThreadLocal<looper>();
     
        public static void prepare() {
           prepare(true);
        }
     
        private static void prepare(boolean quitAllowed) {
           if (sThreadLocal.get() != null) {
               throw new RuntimeException("Only one Looper may be created per thread");
           }
           sThreadLocal.set(new Looper(quitAllowed));
        }
        ...
    }
    

    我们知道,在某一个线程调用sThreadLocal.get()时,得到的是该线程的数据的looper。前面的提到的Looper.prepare()用来在本线程生成一个looper实例在这里的源码中也体现出来了。就是new 一个looper,然后放到ThreadLocal中。并且保证了一个线程只能有一个looper实例。

    todo

    • 在一个线程调用ThreadLocal的get/set方法,为什么得到的就是当前thread的值?
      1. Thread currentThread = Thread.currentThread();这样能得到当前线程的信息。
      2. 然后根据当前线程的信息去ThreadLocal中拿线程对应的值。可以将ThreadLocal理解为一块存储区,将这一大块存储区分割为多块小的存储区,每一个线程拥有一块属于自己的存储区,那么对自己的存储区操作就不会影响其他线程。对于ThreadLocal,则每一小块存储区中就保存了与特定线程关联的Looper。
    • looper的looper()方法做了什么工作?

    相关文章

      网友评论

          本文标题:判断线程以及looper相关

          本文链接:https://www.haomeiwen.com/subject/wdhxmxtx.html