Android 同步机制
摘要
Android系统里面的进程数目以千计,每个进程所需要的资源互相独立而又不干涉,来来往往犹如忙碌的工蚁,辛勤的搬运着“食物”(资源)从遥远的目的地到蚁穴,然后又从蚁穴搬运到更远地方, 如此循环直到老死途中。。。 甚是悲凉
原子操作
- 从化学角度来看,难道是要造弹爆炸世界?[认真脸…..]
- 从代码角度来看,一旦开始了就注定要运行到结束,不会被任何线程调用机制打断,谁让这货就是专一呢?
- 应用场景: 访问一些切换与上下文(contex switch)资源,最好使用原子变量,以防止访问的资源存在被外部修改的可能性
- Android 内部一些列的原子操作(主要有自增、自减、与、或、设置、获取)
int32_t android_atomic_xx(int32_t value, volatile int32_t *addr);
- 原子操作实现原理
- 通过内嵌一段汇编代码(类似代码在kernel中常见), 使用CPU指令来完成特定的动作。
- 内存屏障, 编译器一般的会优化(重排)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!