加入收藏 | 设为首页 | 会员中心 | 我要投稿 常州站长网 (https://www.0519zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 移动互联 > 评测 > 正文

面试多线程同步,你必须要思考的问题

发布时间:2019-07-31 16:43:08 所属栏目:评测 来源:佚名
导读:副标题#e# ReentrantLock的实现网上有很多文章了,本篇文章会简单介绍下其java层实现,重点放在分析竞争锁失败后如何阻塞线程。 因篇幅有限,synchronized的内容将会放到下篇文章。 Java Lock的实现 ReentrantLock是jdk中常用的锁实现,其实现逻辑主语基于A

注意下mutex锁释放的时机,回顾上文中pthread_cond_timedwait的流程,在第2步时就释放了mutex锁,之后调用futex_wait进行休眠,为什么要在休眠前就释放mutex锁呢?原因也很简单:如果不释放mutex锁就开始休眠,那其他线程就永远无法调用signal方法将休眠线程唤醒(因为调用signal方法前需要获得mutex锁)。

在线程被唤醒之后还要在第10步中重新获得mutex锁是为了保证锁的语义(思考下如果不重新获得mutex锁会发生什么)。

cond锁

cond锁的作用其实很简单: 保证对象cond->data的线程安全。 在pthread_cond_timedwait时需要修改cond->data的数据,如增加total_seq(在这个cond上一共执行过多少次wait)增加nwaiters(现在还有多少个线程在wait这个cond),所有在修改及访问cond->data时需要加cond锁。

这里我没想明白的一点是,用mutex锁也能保证cond->data修改的线程安全,只要晚一点释放mutex锁就行了。为什么要先释放mutex,重新获得cond来保证线程安全? 是为了避免mutex锁住的范围太大吗?

该问题的答案可以见评论区@11800222 的回答:

mutex锁不能保护cond->data修改的线程安全,调用signal的线程没有用mutex锁保护修改cond的那段临界区。

pthread_cond_wait/signal这一对本身用cond锁同步就能睡眠唤醒。 wait的时候需要传入mutex是因为睡眠前需要释放mutex锁,但睡眠之前又不能有无锁的空隙,解决办法是让mutex锁在cond锁上之后再释放。 而signal前不需要释放mutex锁,在持有mutex的情况下signal,之后再释放mutex锁。

如何唤醒休眠线程

唤醒休眠线程的代码比较简单,主要就是调用lll_futex_wake。

  1. int 
  2. __pthread_cond_signal (cond) 
  3.  pthread_cond_t *cond; 
  4.  int pshared = (cond->__data.__mutex == (void *) ~0l) 
  5.  ? LLL_SHARED : LLL_PRIVATE; 
  6.  //因为要操作cond的数据,所以要加锁 
  7.  lll_lock (cond->__data.__lock, pshared); 
  8.  /* Are there any waiters to be woken? */ 
  9.  if (cond->__data.__total_seq > cond->__data.__wakeup_seq) 
  10.  { 
  11.  //__wakeup_seq为执行sign与timeout次数的和 
  12.  ++cond->__data.__wakeup_seq; 
  13.  ++cond->__data.__futex; 
  14.  ... 
  15.  //唤醒wait的线程 
  16.  lll_futex_wake (&cond->__data.__futex, 1, pshared); 
  17.  } 
  18.  /* We are done. */ 
  19.  lll_unlock (cond->__data.__lock, pshared); 
  20.  return 0; 

End

本文对Java简单介绍了ReentrantLock实现原理,对LockSupport.park底层实现pthread_cond_timedwait机制做了详细分析。

【编辑推荐】

  1. 2019年值得学习的编程语言,竟然不是Java
  2. 微软宣布 SQL Server 2019 免费支持 Java
  3. 文章马伊俐离婚 网友:这是华为Mate、P系列的分别
  4. Python与C语言、Java、Nodejs、Golang进行性能测试比较
  5. 5种用于前端开发的JavaScript替代方案
【责任编辑:华轩 TEL:(010)68476606】
点赞 0

(编辑:常州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读