软件构造心得(14):从两道期末考试题看待并发的一些思路与技巧(附答案参考)

前言

哈工大的软件构造期末考试题中,最有难度的往往就是多线程了。而很多同学包括我在内,也是上课听的很懂,但是实际操作中出现了很多问题。这篇博文就和大家一起捋捋期末考试题,看看技巧和入手的点在哪里。如有错误恳请指正。另附我们讨论出的陶神佬最终敲定的一份答案,欢迎大家一起来讨论,继续加大复习的深度!


2018年期末考题第二道大题

先po一下笔者认为的有风险的地方。

  1. Lot,Car本身是immutable的,不存在线程危险
  2. 对于ConcreteParkingField,我们首先的保证getOneFreeLot这个东西是安全的。如果这个东西本身不是安全的,那么在上面的代码的第11行就会出现你实际上搞回来一个数字,但是这个数字同时也被别的线程抢走了的情况。而这个方法没有给i相应的具体实现,所以我们只能把这个方法的signatrue加上synchronized。
  3. 回到ParkingThead代码上来,我们看到实际上它的逻辑就是尝试停车,如果没有车位,那么久sleep等待。我们还是按照惯例把切入点放到rep修改上,追踪到了第1行,开始上锁。可能被想到的一种解法就是把第11行道第17行(当前的),都包到锁里面。因为我们要避免先找到一个freelot之后却被另一线程抢停车导致脱离预期的情况,虽然这样有可能会因为sleep锁住很久,但是如果我们选择上锁,就只能这样了,但这样其实并不对(经沈哥指正,因为这样会使得一个线程把锁攥在手里然后因为没有停车位疯狂sleep,直到碰巧在下一次循环开始的时候拿到了锁,这样效率可见的低,而且如果大概率死循环),但是也没办法。经涛哥指正,我们再次考虑会发现11行和17行的分离就是一个离谱的事,其实我们应该将11和17合并,即将17放到11下面,然后这两行上一个锁,这样就最佳了,但其实这样也会产生问题,因为只有在getfreelot不为-1的时候我们才能停车,也就是如果这样的话,会出现在pf.parking中出问题,所以更进一步的,我们应该加上一个if判断,这样就完美了

本题总结

1. sleep不会交出来锁。带着锁sleep。
2. 更优化的办法实际上是使用wait和notifyAll,让这个线程wait,然后交出来锁,别的线程停车完事再notify停车,但这个不是我们需要掌握的核心知识。

近两年试题答案参考

感谢王忠杰老师的栽培,感谢刘铭老师的答疑,感谢粉丝群的讨论工作,感谢陶新昊神佬的整理,将近两年哈工大软构的答案整理放在如下链接,粉丝群出品,必属精品:
(陶佬说不让膜他,可是我们必须膜。老铁,我做的对吗br> https://share.weiyun.com/rw2VYlbU

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年6月6日
下一篇 2020年6月6日

相关推荐