当前位置:网站首页>頭條面試居然跟我扯了半小時的Semaphore
頭條面試居然跟我扯了半小時的Semaphore
2022-04-22 09:52:00 【萬猫學社】
一個長頭發、穿著清爽的小姐姐,拿著一個嶄新的Mac筆記本向我走來,看著來勢汹汹,我心想著肯定是技術大佬吧!但是我也是一個才華橫溢的人,穩住我們能贏。

面試官:看你簡曆上有寫熟悉並發編程,Semaphore一定用過吧,跟我說說它!
我:Semaphore是JDK提供的一個同步工具,它通過維護若幹個許可證來控制線程對共享資源的訪問。 如果許可證剩餘數量大於零時,線程則允許訪問該共享資源;如果許可證剩餘數量為零時,則拒絕線程訪問該共享資源。 Semaphore所維護的許可證數量就是允許訪問共享資源的最大線程數量。 所以,線程想要訪問共享資源必須從Semaphore中獲取到許可證。
面試官:Semaphore有哪些常用的方法?
我:有acquire方法和release方法。 當調用acquire方法時線程就會被阻塞,直到Semaphore中可以獲得到許可證為止,然後線程再獲取這個許可證。 當調用release方法時將向Semaphore中添加一個許可證,如果有線程因為獲取許可證被阻塞時,它將獲取到許可證並被釋放;如果沒有獲取許可證的線程, Semaphore只是記錄許可證的可用數量。
面試官:可以舉一個使用Semaphore的例子嗎?
我:張三、李四和王五和趙六4個人一起去飯店吃飯,不過在特殊時期洗手很重要,飯前洗手也是必須的,可是飯店只有2個洗手池,洗手池就是不能被同時使用的公共資源,這種場景就可以用到Semaphore。
面試官:可以簡單用代碼實現一下嗎?
我:當然可以,這是張三、李四、王五和趙六的顧客類:
然後,寫一個測試類模擬一下他們洗手的過程:
運行以後的結果應該是這樣的:
可以看到,當已經有兩個人在洗手的時候,其他人就被阻塞,直到有人洗手完畢才是開始洗手。
面試官:對Semaphore的內部原理有沒有了解?
我:Semaphore內部主要通過AQS(AbstractQueuedSynchronizer)實現線程的管理。Semaphore在構造時,需要傳入許可證的數量,它最後傳遞給了AQS的state值。線程在調用acquire方法獲取許可證時,如果Semaphore中許可證的數量大於0,許可證的數量就减1,線程繼續運行,當線程運行結束調用release方法時釋放許可證時,許可證的數量就加1。如果獲取許可證時,Semaphore中許可證的數量為0,則獲取失敗,線程進入AQS的等待隊列中,等待被其它釋放許可證的線程喚醒。
面試官:嗯,不錯。在您的代碼中,這4個人會按照線程啟動的順序洗手嘛?
我:不會按照線程啟動的順序洗手,有可能趙六比王五先洗手。
面試官:為什麼會出現這種情况?
我:因為在我的代碼中,使用Semaphore的構造函數是這個:
在這個構造函數中,使用的是NonfairSync(非公平鎖),這個類不保證線程獲得許可證的順序,調用acquire方法的線程可以在一直等待的線程之前獲得一個許可證。
面試官:有沒有什麼方法可保證他們的順序?
我:可以使用Semaphore的另一個構造函數:
在調用構造方法時,fair參數傳入true,比如:
這樣使用的是FairSync(公平鎖),可以確保按照各個線程調用acquire方法的順序獲得許可證。
面試官:嗯,不錯。NonfairSync和FairSync有什麼區別?為什麼會造成這樣的效果?
我:這就涉及到NonfairSync和FairSync的內部實現了。
在NonfairSync中,acquire方法核心源碼是:
release方法核心源碼是:
當一個線程A調用acquire方法時,會直接嘗試獲取許可證,而不管同一時刻阻塞隊列中是否有線程也在等待許可證,如果恰好有線程C調用release方法釋放許可證,並喚醒阻塞隊列中第一個等待的線程B,此時線程A和線程B是共同競爭可用許可證,不公平性就體現在:線程A沒任何等待就和線程B一起競爭許可證了。
而在FairSync中,acquire方法核心源碼是:
和非公平策略相比,FairSync中多一個對阻塞隊列是否有等待的線程的檢查,如果沒有,就可以參與許可證的競爭;如果有,線程直接被插入到阻塞隊列尾節點並掛起,等待被喚醒。
面試官:嗯,很不錯,馬上給你發offer。
本故事純屬虛構,如有雷同實屬巧合
版权声明
本文为[萬猫學社]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204220902452039.html
边栏推荐
- JS clich é about this, constructor, prototype
- 云原生爱好者周刊:寻找 Netlify 开源替代品
- 超越iTerm! 号称下一代终端神器,功能贼强大!
- etcd Watch 异常场景
- 中商惠⺠交易中台架构演进:对 Apache ShardingSphere 的应⽤
- How to select Bi tools? These three questions are the key
- L2-032 rainbow bottle (25 points) (stack)
- [flutter topic] 125 illustrated autobiography ace_ ICON. Ttf Icon Library
- L2-033 simple calculator (25 points)
- QT event filter instance
猜你喜欢
随机推荐
【Go】程序流程控制
QT AxObject库的简单操作
Nacos
shell获取随机数和echo -e '\033[字背景颜色;字体颜色m字符串\033[0m'
matplotlib教程04---绘制常用的图形
Leapftp: 425 failed to establish connection solution
云原生爱好者周刊:寻找 Netlify 开源替代品
MySQL多实例安装方法一
深度学习遥感场景分类数据集整理
中商惠⺠交易中台架构演进:对 Apache ShardingSphere 的应⽤
SQL syntax
Deep learning remote sensing scene classification data set sorting
内存管理-
OGG-00663 OCI Error ORA-02396: exceeded maximum idle time
MySQL multi instance installation method I
SQL data type
Zhezheng nail scanning code login
Dext diagnostic database supporting AUTOSAR classic and adaptive platform
getimagesize()函数获取图片宽高取反
idea写sparksql程序local[*]模式可以运行,提交到spark yarn运行出现ClassNotFoundException









