从安卓Handler到java关键字volatile

安卓中线程间通信是通过Handler来进行的。而Handler的原理是Loop在维持一个全局静态的ThreadLocal对象,ThreadLocal对象里面通过以线程对象为key,Loop对象为值来存储每个线程自己的Loop.在每个线程new一个Handler的之前都要调用Looper.prepare();就是为了给当前线程创建自己的Loop,而在创建Handler的时候需要获取到当前线程的Loop,这就是为什么要先调用Looper.prepare()的原因。

而线程的Loop对象里面又维护一个messagequeue(这个Messagequeue里面有一个Message实例,所有的消息都是使用Message链表来存储的),每次Handler发送Message的时候都是将消息根据延迟时间的先后存入messagequeue的链表中,那消息什么时候进行处理咧?这就是为什么子线程创建Handler的时候要调用Looper.loop()的原因了,loop()函数会建立一个循环来从messagequeue中获取Message,如果没有就等待,如果有就处理。

这就是Handler实现进程间通信的原理,其实底层原理就是维持一个全局的静态队列,只不过这个静态队列中保存的是线程ID和Looper实例。也就是说每个线程如果用到Handler都需要创建一个自己的Looper对象。

既然Handler可以在多个线程中访问,这就涉及到了线程同步的问题了,源码中主要用到了volatile和synchronized,来处理线程同步问题。这里说一下volatile和synchronized的区别。

  1. volatile:相当于对对象进行原子操作,java中进程有一个主内存,每个线程还有自己的工作内存,线程自己的工作内存会保留自己要用到的变量的副本,要用到这个变量的时候都是直接去使用这个副本。而加上了volatile关键字修饰的变量,线程每次使用该变量时都是去主内存中去获取该变量的最新值,这个只能保证操作的原子性,并不能保证线程操作的顺序,所以还是会出现问题。(用volatile修饰之后并不是所有的操作都是原子性的,比如n++,n=n+1这种涉及到变量的上一次的值的操作就不是原子的了,这时候就需要加上synchronized来同步)

  2. synchronized:加锁,可以修饰类,方法,代码块,多线程访问时需要先去获取锁权限,获取到之后才能开始执行,否则就阻塞等待。能保证线程执行的顺序。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值