欧美日韩国产一区二区|qovd片|小明个人发布看看|小浪货你夹真紧水又多|老头把我添高潮了A片故|99热久久精品国产一区二区|久久久春色AV

阿里巴巴|阿里技術三面:哲學家進餐( 二 )


4個哲學家持有叉子?故最多只允許 4 個哲學家去持有叉子 , 可保證至少有 1個哲學家能吃上意大利面(即獲得到 2 個叉子) 。
因為最差情況下是:4 個哲學家都各自持有1個叉子 , 此時還剩余 1個叉子可供使用 , 這 4個哲學家中必然有1人能獲取到這個剩余的 1 個叉子 , 從而手持 2個叉子 , 可以吃意大利面 。
即:4 個人中 , 1 個人有 2 個叉子 , 3 個人各持 1 個叉子 , 共計 5 個叉子 。
3個哲學家持有叉子?既然最多只允許4個哲學家去持有叉子 , 那么如果只允許 3 個哲學家去持有叉子是否可行呢?
當然可行 , 3個哲學家可以先都各自持有 1 把叉子 , 此時還剩余 2 把叉子;
當這 3 個哲學家剛好都相鄰(比如:編號為圖中的 0 1 2 ) , 可能會造成只有 1 個哲學家能吃到意面的情況 , 具體而言即 0號哲學家拿到了其左側的叉子(編號為 1 ) ,1號哲學家也拿到了其左側的叉子(編號為 2 ) , 2 號哲學家也拿到了其左側的叉子(編號為 3 ) , 此時只有 0號哲學家能拿到其右側的叉子(編號為 0 ) , 因此只有 0 號哲學家能吃到意面 。
而其余情況下 , 3個哲學家中都能有 2人吃到意面 。
即:3 個人中 , 2 個人各自持有 2 個叉子 , 1 個人持有 1 個叉子 , 共計 5 個叉子 。
并且仔細想想 , 叉子的數目是固定的(個數為 5 ) , 直覺上來講 3 個人去搶 5 個叉子比 4 個人去搶 5 個叉子效率高 。
方法一:信號量用Semaphore去實現上述的限制:Semaphore eatLimit = new Semaphore(4);
一共有5個叉子 , 視為5個ReentrantLock , 并將它們全放入1個數組中 。
給叉子編號 0 1 2 3 401234(對應數組下標) 。
代碼具體實現:

改進:
位運算就可以表示5個叉子的使用狀態 , 只需用1個volatile修飾的int變量即可 + CAS操作即可 , 即AtomicInteger類 。
代碼具體實現:

方法二:只允許1個哲學家就餐設置 1 個臨界區以實現 1 個哲學家 “同時”拿起左右 2 把叉子的效果 。
即進入臨界區之后 , 保證成功獲取到左右 2 把叉子并執行相關代碼后 , 才退出臨界區 。
方法2有一定的概率是“并行” , “只允許1個哲學家就餐”是嚴格的“串行” 。
代碼如下:

改進:
位運算就可以表示5個叉子的使用狀態 , 只需用1個volatile修飾的int變量即可 + CAS操作即可 , 即AtomicInteger類 。

方法一和方法二的區別2 者之間有細微的差別:
方法 2 是在成功拿起左右叉子之后就退出臨界區 , 而“只讓 1 個哲學家就餐”是在拿起左右叉子 + 吃意面 + 放下左右叉子一套流程走完之后才退出臨界區 。
前者的情況可大概分為 2 種 , 舉具體例子說明(可參照上面給出的圖片):

  • 1 號哲學家拿起左右叉子( 1 號叉子 + 2 號叉子)后就退出臨界區 , 此時 4 號哲學家成功擠進臨界區 , 他也成功拿起了左右叉子( 0 號叉子和 4 號叉子) , 然后就退出臨界區 。
  • 1 號哲學家拿起左右叉子( 1 號叉子 + 2 號叉子)后就退出臨界區 , 此時 2 號哲學家成功擠進臨界區 , 他需要拿起 2 號叉子和 3 號叉子 , 但 2 號叉子有一定的概率還被 1 號哲學家持有( 1 號哲學家意面還沒吃完) , 因此 2 號哲學家進入臨界區后還需要等待 2 號叉子 。 至于 3 號叉子 , 根本沒其他人跟 2 號哲學家爭奪 , 因此可以將該種情況視為“ 2 號哲學家只拿起了 1 只叉子 , 在等待另 1 只叉子”的情況 。
總之 , 第1種情況即先后進入臨界區的 2 位哲學家的左右叉子不存在競爭情況 , 因此先后進入臨界區的 2 位哲學家進入臨界區后都不用等待叉子 , 直接就餐 。 此時可視為 2 個哲學家在同時就餐(當然前 1 個哲學家有可能已經吃完了 , 但姑且當作是 2 個人同時就餐) 。

相關經驗推薦