android中的 sp,wp学习笔记

来源:互联网 发布:淘宝店铺客服分流设置 编辑:程序博客网 时间:2024/05/29 16:49


1.如何才能支持sp,wp
  只支持sp的情况,只要实现下面2个函数就行
  class simpleRefbase{
   void incStrong(const void* id);
   void decStrong(const void* id);
  };这就是我们常规实现的简单引用计数方法。
  android已经帮我们实现了一个LightRefBase<T>
 

  支持sp并且支持wp
  需要继承 android实现的RefBase
  class RefBase{
    void incStrong(const void* id); 
    void decStrong(const void* id);
   
    weakref_type* createWeak(const void* id);
    影子对象,监控sp,wp的使用情况,其实这个对象主要就是围绕下面的mRefs进行的
    weakref_impl* mRefs;
  }

2. RefBase每次new RefBase的时候,都会伴随着new一个影子对象new ref,
   RefBase(){
     mRefs=new weakref_impl();
   }
   
   影子对象就是监控着这个RefBase的使用情况的,主要包括sp了多少次 strong,wp了多少次 weak,监控的那个对象base。
   当最后一个sp被干掉的时候(strong==0),就delete base, 当最后一个wp被干掉的(weak==0),就delete ref
   ~RefBase{
         if(weak==0)
           delete mRefs;
    }

3.那什么时候会执行析构函数呢?
  strong==0 就是最后一个sp被干掉的时候,
  delete base;--> ~RefBase(){} 

4. sp,wp
   强指针
   classe sp<T>{
      T* base;
   }
   只要存在这样的对象,则内部保存的指针就是有效的base!=null,sp会同时增加强弱引用计数 strong++,weak++

   弱指针
   class wp<T>{
     T* base;
     void* ref;  ref其实就指向base->mRefs
   }
   只要存在这样的对象,则内部保存的指针使用情况的对象(ref)就有效的,而base不一定有效。

   弱引用计数一定大于等于强引用计数

5. 那这样需要怎样使用wp中的base呢?
   因为base的生命周期只跟sp(strong)有关,所有现在无法确定wp中的base是否有效,这就需要一系列的判断的。 

   ref->attempIncStrong判断是否能增加强引用计数,如果能则base有效,也就是可以有wp生成一个sp。
   sp<T>  =wp<T>->promoto();

   attempIncStrong分析
   (1).是否第一次引用base  , strong原始值==INITIAL_STRONG_VALUE,返回true
   (2).是否有其他sp引用了base , strong原始值>0,返回true
   (3).是否其他sp引用了base,但是有其他多线程的地方释放了sp ,造成strong原始值<=0,返回false
  
6. attempIncStrong
    int cur=ref->mStrong;
    //如果对象被强引用多(cur!=INITIAL_STRONG_VALUE),并且还有有效的sp(强引用计数>0),则进入while,对Strong+1
    //while主要目的是防止多线程操作m_Strong,造成数据的不一致
    while(cur>0&&cur!=INITIAL_STRONG_VALUE){
         if(android_atomic_cmpcchg(cur,cur+1,&ref->m_Strong)==0)
            break;
         cur=ref->m_Strong;
    }
    

    //如果没有强引用过
    if(cur==INITIAL_STRONG_VALUE){
    
    }

    //如果多线程释放过sp
    if(cur<=0){
   
    }
  
7.还存在疑问的地方

问题1. 
线程1进行释放 sp1<xx>   ~sp1<xx>  
void  decStrong()
{
1.   int c=android_atomic_dec(&mStrong);
2.   if(c==1){
3.       onLastStrongRef();
4.       delete this;
5.    }
6.    decWeak();
}

线程2进行构造 sp2<xx>=sp1<xx>
void incStrong(){
1.     incWeak();
2.     int c=android_atomic_dec(&mStrong);   
}
  
当线程1 执行decStrong line1返回c=1,同时线程2执行incStrong line2,返回c=0.
这是sp2<T>已经指向一个无效的对象了。这个如何解呢?如果真存在这个问题那RefBase中很多地方存在incWeak,attempincStrong...

问题2.
  attempIncStrong中好像进行了2次的增加强引用
  android_atomic_cmpxchg()
  android_atomic_inc()
  这个又如何解呢。
求明白的给指正一下

0 0
原创粉丝点击