Android 同步机制

本文详细探讨了Android系统的同步机制,包括原子操作、Native层的互斥锁和Android特有的Autolock,以及Java层的`synchronized`关键字。此外,还介绍了Android消息机制,如Looper、Message和Handler在多线程通信中的重要作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android 同步机制


摘要

Android系统里面的进程数目以千计,每个进程所需要的资源互相独立而又不干涉,来来往往犹如忙碌的工蚁,辛勤的搬运着“食物”(资源)从遥远的目的地到蚁穴,然后又从蚁穴搬运到更远地方, 如此循环直到老死途中。。。 甚是悲凉

原子操作

  • 从化学角度来看,难道是要造弹爆炸世界?[认真脸…..]
  • 从代码角度来看,一旦开始了就注定要运行到结束,不会被任何线程调用机制打断,谁让这货就是专一呢?
  • 应用场景: 访问一些切换与上下文(contex switch)资源,最好使用原子变量,以防止访问的资源存在被外部修改的可能性
  • Android 内部一些列的原子操作(主要有自增、自减、与、或、设置、获取)
  int32_t android_atomic_xx(int32_t value, volatile int32_t *addr); 


  • 原子操作实现原理

  1. 通过内嵌一段汇编代码(类似代码在kernel中常见), 使用CPU指令来完成特定的动作。
  2. 内存屏障, 编译器一般的会优化(重排)CPU指令执行顺序,但是涉及到资源区访问问题,CPU指令顺序则不能被打乱,此时候就需要考虑到限制优化 –即是: 内存屏障(会起到该作用 )。

Native层同步机制

  • 互斥锁
     class Mute{
         ...
         status_t lock();
         void     unlock();
         status_t trulock();
     };

对于Andoid Native中临界区访问常用的保护手段即是:使用互斥锁
当然,lock与unlock需要配对使用,否则极易造成死锁

    eg. 
    Mute g_mutex;
    int GetWiFiConnectApStatus(void)
    {
        ....
        g_mutex.lock();
        //do something ;
        g_mutex.unlock();// here is important 
    }


  • Autolock

a. 从字面上看为auto, 但其实还有缺陷。
b. 因为它的unlock是在析够函数里面完成的。但是,如果出现文件中有两个以上的资源需求者访问被锁定的资源时,那么会出现有永远拿不到锁情况(即死锁)。
c. 故此,不建议使用这种不太健全的autolock机制,除非你能控制死锁情况发生。

Java层同步机制

  • Java中的世 界如何完成同步? 当然也会用到锁,它的锁构成形式是怎样?
  • synchronized() 同步关键字
  a. 保护一段代码
   class FooA{
        ...
        synchronized(mLock)
        {
            ......
        }
}
 b. 修饰类方法
   class FooA{
    .....
    public synchronized int lockMethod(Sting Ap){....}
    public synchronized void unlockMethod(void){....}
    ....
}
c. 修饰类
    synchronized (FooA.class){....}
    这种上的修饰相当于对整个对象做了限制应用,这个情况需要严谨考虑使用 

Android 消息机制

  • android 进程消息框架
    如下图,android进程之间的信息我们大家共知的是通过Binder,而线程之间是通过以下几大类:Looper类Message类Handler类

这里写图片描述

  • Looper类
    每个线程创建一个Looper对象,其内部维护一个Message消息队列,所有线程消息队列都会被存放在该目录里。Looper对象里会根据不同的状态选择对应的Handler去处理消息。

  • Message类
    消息的运载体,与我们共知的Binder中的Parcelable类有着共同的属性,因为其为Parcelable的派生类

  • Handler类
    Handler对应的为状态机,Message的内容都会得到它对应的状态机的handle,以一个不恰当的比喻来说handler是最为繁忙的、也是最实在干活的类,他永远不停的在处理源源不断的Message队列中的Message!

Android 中的同步机制主要用于解决多线程环境下的资源共享和数据一致性问题。由于 Android 应用程序通常运行在一个多任务环境中,多个线程可能会同时访问共享资源(如变量、文件或数据库)。为了防止发生竞态条件或其他并发问题,开发者需要通过适当的同步手段来保护关键区域。 以下是几种常见的 Android 同步机制: ### 1. **synchronized 关键字** `synchronized` 是 Java 提供的一种内置同步工具,在 Android 开发中也经常使用。它可以用作方法修饰符或者代码块关键字。 - 当用于整个方法时,表示该方法在同一时刻只能由一个线程执行; - 如果作用于某个特定对象实例,则只有获取到此对象锁的线程才能进入相应的 synchronized 块。 示例: ```java public class Counter { private int count = 0; public synchronized void increment() { // 对方法加锁 count++; } public synchronized int getCount() { return count; } } ``` ### 2. **ReentrantLock 类** 相比 `synchronized`, ReentrantLock 更为灵活,支持更复杂的锁定协议。例如可以尝试非阻塞地获得锁 (tryLock()), 或者指定等待时间等特性。 例子: ```java import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class BankAccount { private double balance; final Lock lock = new ReentrantLock(); public void deposit(double amount) { lock.lock(); // 获取锁 try { if(amount > 0){ balance += amount; } } finally{ lock.unlock(); // 确保最后释放锁 } } public void withdraw(double amount){...} } ``` ### 3. **Handler 和 Looper** 虽然不是传统意义上的“同步”方案,但在处理 UI 更新和其他跨线程通信场景下非常有用。每个消息队列都关联了一个 Handler 来调度任务,并保证所有操作都在单一主线程上完成。 总结来说,选择合适的同步策略取决于应用程序的具体需求以及性能考量因素。如果只是简单的情况,默认采用 synchronized 就足够了;对于复杂情形则考虑利用高级库如 ReentrantReadWriteLock 或 Atomic 变量类族。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值