前言:由於 LeetCode Concurrency(併發) 還沒有 Go 語言版本,我先自行用 Go 語言來解題。為了能在 LeetCode 以外的平台獲得討論,所以我打算逐漸把自己的解題思路寫下。這是我試水溫的第二篇。
本題 LeetCode 連結:
https://leetcode.com/problems/print-in-order/
本題考核點?
指定各種不同順序執行 First()
, Second()
, Third()
三個 goroutine,但三者都必須以不變順序印出字串,印出順序不受順序執行影響。
goroutine 若不刻意控制,將無法保證執行的先後順序,因此本題就是要考核對 goroutine 順序控制的能力。
解法與思路:
1. 所用 Channel 型態與定位?
本題採用三個 unbuffered channel,並且串在一個 slice 裡。
1 | // make an array of unbuffered |
分別是:
streamSync[0]
:First()
交棒給Second()
streamSync[1]
:Second()
交棒給Third()
streamSync[2]
:Third()
交棒給PrintInOrder()
2. 三個(或說四個) goroutine 之間,如何交接棒?
一開始由 PrintInOrder()
依照指定順序啟動三個 goroutine。
再看這三個 goroutine,只有 First()
可以不受限執行 Print,其餘都必須等待各自的 streamSync[i]
訊號,因此可以保證 “First” 先被印出。
1 | func First(streamSync [3]chan interface{}) { |
1 | func Second(streamSync [3]chan interface{}) { |
1 | func Third(streamSync [3]chan interface{}) { |
-
當 “First” 先被印出之後,交棒給
streamSync[0]
,然後…- 被
streamSync[0]
卡住的Second()
就可以印出 “Second” - 被
streamSync[1]
卡住的Third()
繼續等待訊號 - 被
streamSync[2]
卡住的PrintInOrder()
繼續等待訊號
- 被
-
當 “Second” 繼續被印出之後,交棒給
streamSync[1]
,然後…- 被
streamSync[1]
卡住的Third()
就可以印出 “Third” - 被
streamSync[2]
卡住的PrintInOrder()
繼續等待訊號
- 被
-
當 “Third” 最後被印出之後,交棒給
streamSync[2]
,然後…- 被
streamSync[2]
卡住的PrintInOrder()
就可以往下執行,最後程式順利結束。
- 被
完整解題程式碼:
本題解答程式碼已經窮舉這三個 goroutine 所有啟動順序。
https://play.golang.org/p/cklu-vaxF6w