选择遗忘|面试官:这个经典的并发问题用 Go 语言如何实现?( 三 )

<-this.streamForks[leftNum] //把已经拿起来的左边筷子释放出去PutLeftFork(philosopher)}default: //无法拿起左边筷子fmt.Printf("Philosopher %d can't pick fork %d.\n", philosopher, leftNum)}this.missingDoubleForkTimes++Think() }}这边对于每一只筷子的具体表现就是一个 buffered channel , 回圈流程如下:

  1. 先尝试把自己的号码塞入左边的 buffered channel
  2. 成功了 , 就是抢到一只筷子 , 往下 。
  3. 失败了 , 跳到「default: //无法拿起左边筷子」 , 思考一下 , 然后从头开始 。
  4. 再尝试把自己的号码塞入右边的 buffered channel
  5. 成功了 , 就是抢到两只筷子 , 开始吃 , 吃饱离开 , 退出餐桌 。
  6. 失败了 , 跳到「default: //无法拿起右边筷子」 , 把已经抢到的左边筷子还回去 , 思考一下 , 然后从头开始 。
在 console 输出 , 可以看到代表每一位哲学家的 goroutine 详细动作过程 , 错过筷子次数并不多 , 大部分执行结果的错过次数在 3~5 次(点击以下的「完整解题代码」就能体验) 。
完整解题代码:
示意图:
选择遗忘|面试官:这个经典的并发问题用 Go 语言如何实现?


推荐阅读