| park方法用POSIX的pthread_cond_timedwait方法阻塞线程,调用pthread_cond_timedwait前需要先获得锁,因此park主要流程为: 
    调用pthread_mutex_trylock尝试获得锁,如果获取锁失败则直接返回调用pthread_cond_timedwait进行等待调用pthread_mutex_unlock释放锁 另外,在阻塞当前线程前,会调用OSThreadWaitState的构造方法将线程状态设置为CONDVAR_WAIT,在Jvm中Thread状态枚举如下  enum ThreadState {  ALLOCATED, // Memory has been allocated but not initialized  INITIALIZED, // The thread has been initialized but yet started  RUNNABLE, // Has been started and is runnable, but not necessarily running  MONITOR_WAIT, // Waiting on a contended monitor lock  CONDVAR_WAIT, // Waiting on a condition variable  OBJECT_WAIT, // Waiting on an Object.wait() call  BREAKPOINTED, // Suspended at breakpoint  SLEEPING, // Thread.sleep()  ZOMBIE // All done, but not reclaimed yet }; 
 Linux的timedwait 由上文我们可以知道LockSupport.park方法最终是由POSIX的 pthread_cond_timedwait的方法实现的。  我们现在就进一步看看pthread_mutex_trylock,pthread_cond_timedwait,pthread_mutex_unlock这几个方法是如何实现的。 Linux系统中相关代码在glibc库中。 pthread_mutex_trylock 先看trylock的实现, 代码在glibc的pthread_mutex_trylock.c文件中,该方法代码很多,我们只看主要代码 //pthread_mutex_t是posix中的互斥锁结构体 int __pthread_mutex_trylock (mutex)  pthread_mutex_t *mutex; {  int oldval;  pid_t id = THREAD_GETMEM (THREAD_SELF, tid); switch (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex),  PTHREAD_MUTEX_TIMED_NP))  {  case PTHREAD_MUTEX_ERRORCHECK_NP:  case PTHREAD_MUTEX_TIMED_NP:  case PTHREAD_MUTEX_ADAPTIVE_NP:  /* Normal mutex. */  if (lll_trylock (mutex->__data.__lock) != 0)  break;  /* Record the ownership. */  mutex->__data.__owner = id;  ++mutex->__data.__nusers;  return 0;  } }   //以下代码在lowlevellock.h中   #define __lll_trylock(futex)   (atomic_compare_and_exchange_val_acq (futex, 1, 0) != 0)  #define lll_trylock(futex) __lll_trylock (&(futex)) 
 mutex默认用的是PTHREAD_MUTEX_NORMAL类型(与PTHREAD_MUTEX_TIMED_NP相同);  因此会先调用lll_trylock方法,lll_trylock实际上是一个cas操作,如果mutex->data.lock==0则将其修改为1并返回0,否则返回1。 如果成功,则更改mutex中的owner为当前线程。 pthread_mutex_unlock (编辑:宣城站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |