首页 > 代码库 > Android开发之Thread类分析 (转载)

Android开发之Thread类分析 (转载)

  转自:http://blog.csdn.net/llping2011/article/details/9706599

 

       在我们Linux系统中创建线程函数为:pthread_create(),在Android中我们为线程封装了一个类Thread,实际调用的还是pthread_create()
当我们想创建线程的时候,只需要继承于这个Thread类并实现虚函数thread_loop()即可。

 

    frameworks/base/include/utils/threads.h      class Thread : virtual public RefBase      {      public:          // 创建一个Thread对象,但是并不立即启动线程函数          Thread(bool canCallJava = true);          virtual ~Thread();          // 开始启动线程函数,调用的是threadLoop          virtual status_t run(const char*name = 0, int32_t prority = PRIORITY_DEFAULT,                      size_t stack = 0);          // 申请退出这个线程          virtual void requestExit();          virtual status_t readyToRun();          // 调用requestExit()等待直到这个线程退出              status_t requestExitAndWait();          // 等待直到线程退出,如果没有启动立即返回              status_t join();      protected:          // 如果调用了requestExit()返回true          bool exitPending() const;      private:          // 这是实际的线程函数,继承类必须实现它,          // 返回true的话再次调用,返回false的话就会退出          virtual bool threadLoop() = 0;          // 禁止赋值          Thread& operator = (const Thread&);          // 内部类,被run函数调用,实际调用threadLoop          static int _threadLoop(void* user);          const bool mCanCallJava;              thread_id_t mThread;    // thread_id_t 其实是 void*类型          mutable Mutex mLock;              Condition mThreadExitedCondition;              status_t mStatus;          // 注意:所以操作这两个变量的地方都需要上锁          volatile bool mExitPending;          volatile bool mRunning;              sp<Thread> mHoldSelf;      };  

 

我们首先看下Thread类的构造函数:

 

    Thread::Thread(bool canCallJava)           :   mCanCallJava(canCallJava),              mThread(thread_id_t(-1)),              mLock("Thrad::mLock"),              mStatus(NO_ERROR),              mExitPending(false), mRunnig(false)      {}  

 

真正启动线程的函数:

    status_t Thread::run(const char*name, int32_t priority, size_t stack)      {          Mutex::Autolock _l(mLock);          if(mRunnig)              return INVALID_OPERATION;          mState = NO_ERROR;          mExitPending = false;          mThread = thread_id_t(-1);          mHoldSelf = this;   // 保存着当前对象的引用          mRunning = true;          if (mCanCallJava)               res = createThreadEtc(_threadLoop, this, name, priority, stack, &mThread);          else              res = androidCreateRawThreadEtc(_threadLoop, this, name,                       priority, stack, &mThread);          if(res == false) {              mStatus = UNKNOWN_ERROR;              mRunning = false;              mThread = thread_id_t(-1);              mHoldSelf.clear();              return UNKNOWN_ERROR;          }          return NO_ERROR;      }      这里有个判断mCanCallJava是个什么东西?接着往下看      inline bool createThreadEtc(thread_func_t entryFunction, void* userData,                  const char* threadName = "android:unnamed_thread",                  int32_t threadPriority = PRIORITY_DEFAULT,                  size_t threadStackSize = 0,                  thread_id_t *threadId = 0)      {          return androidCreateThreadEtc(entryFunction, userData, threadName, threadPriority,              threadStackSize, threadId) ? true : false;      }             int androidCreateThreadEtc(thread_func_t entryFunction,                   void* userData,                  const char* threadName,                  int32_t threadPriority = PRIORITY_DEFAULT,                  size_t threadStackSize = 0,                  thread_id_t *threadId = 0)      {          return gCreateThreadFn(entryFunction, userData, threadName, threadPriority,              threadStackSize, threadId);      }  

我们看到最后调用的是gCreateThreadFn这个函数,而gCreateThreadFn是个全局的函数指针,
static android_create_thread_fn gCreateThreadFn = androidCreateRawThreadEtc;
这里默认给它赋值为 androidCreateRawThreadEtc,这跟前面调用的是一样的???

既然是函数指针肯定有给它赋值的地方:

    void androidSetCreateThreadFunc(android_create_thread_fn func)      {          gCreateThreadFn = func;      }  

那这个函数在什么地方调用的呢?又给它赋什么值了呢?
我们找到了再AndroidRuntime类里面启动虚拟机的地方:

    int androidRuntime::startReg(JNIEnv* env)      {          androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);          return 0;      }  

这样如果我们的mCanCallJava如果为true的话,调用的就是:

    int AndroidRuntime::javaCreateThreadEtc(android_thread_func_t entryFunction,                      void* userData,                      const char* threadName,                      int32_t threadPriority,                      suze_t threadStackSize,                      android_thread_id_t *threadId)      {          void** args = (void**)malloc(3*sizeof(void*));          args[0] = (void*)entryFunction;          args[1] = userData;          args[2] = (void*)strdup(threadName);          return androidCreateRawThreadEtc(AndroidRuntime::javaThreadShell, args.              threadName, threadPriority, threadStackSize, threadId);      }  

最后调用的还是同一个创建线程的函数只是回调函数不一样,这里变成了AndroidRuntime::javaThreadShell

    int AndroidRuntime::javaCreateThreadEtc(void* args)      {          voir* start = ((void**)args)[0];          voir* userData = http://www.mamicode.com/((void**)args)[1];          voir* name = ((void**)args)[2];          free(args);          JNIEnv* env;                    javaAttachThread(name, &env);          result = (*(android_thead_func_t)start)(userData);          javaDetachThread();                    free(name);          return result;      }  

这里线程函数javaThreadShell里面还是调用前面我们的_threadLoop函数,只不过在调用之前,调用
了javaAttachThread()将线程attach到JNI环境中去了,这样线程函数就可以调用JNI函数,最后线程
函数退出之后再调用javaDetachThread()退出JNI环境。

现在进入线程函数_threadLoop(),这是一个static函数

    int Thread::_threadLoop(void* user)      {          Thread* const self = static_cast<Thread*>(user);          sp<Thead> strong(self->mHoldSelf);          wp<Thead> weak(strong);          self->mHoldSelf.clear();                    bool first = true;                    do {    // 进入一个循环,通过判断返回值和内部退出标志位决定是否退出线程              bool result;              if (fisr) {                  first = false;                  self->mStatus = self->readyToRun();                  result = (self->mStatus == NO_ERROR);                  if (result && !self->exitPendind()) {    // 检查是否退出                      result = self->threadLoop(); // 调用实际线程函数                  }              } else {                  result = self->threadLoop();              }                            {                  Mutex::Autolock _l(self->mLock);                  if (result == false || self->mExitPending) {                      self->mExitPending = true;                      self-mRunning = false;                      self->mThread = thread_ir_t(-1);                      self->mThreadExitedCondition.broadcast();                      break;                  }                            }              strong.clear();              strong = weak.promote();          } while(strong != 0);          return 0;      }  

在这里线程退出的条件为:
1)result = true 意味着子类在实现的threadLoop函数中返回false,这样线程就主动退出了
2)mExidPendding = true 这个变量值由Thread类的requestExit函数设置,这样线程就被动退出了。
最后如果线程退出了需要进行些去初始化操作,设置线程运行状态,广播告知其他关心这个线程的对象。

最后,如果我们想使用线程类:  1)创建一个类如MyThread,继承与Thead类  2)在MyThread类中实现父类的纯虚函数threadLoop,也就是我们调用pthread_create时传入的线程函数。  3)定义一个MyThread变量 thread,调用线程的run()方法,启动函数 

 

Android开发之Thread类分析 (转载)