本文通過代碼講解如何實現一個線程池。代碼(來自https://gobyexample.com/)及注釋如下:
package main import "fmt" import "time" //這個是工作線程,處理具體的業務邏輯,將jobs中的任務取出,處理后將處理結果放置在results中。 func worker(id int, jobs <-chan int, results chan<- int) { for j := range jobs { fmt.Println("worker", id, "processing job", j) time.Sleep(time.Second) results <- j * 2 } } func main() { //兩個channel,一個用來放置工作項,一個用來存放處理結果。 jobs := make(chan int, 100) results := make(chan int, 100) // 開啟三個線程,也就是說線程池中只有3個線程,實際情況下,我們可以根據需要動態增加或減少線程。 for w := 1; w <= 3; w++ { go worker(w, jobs, results) } // 添加9個任務后關閉Channel // channel to indicate that's all the work we have. for j := 1; j <= 9; j++ { jobs <- j } close(jobs) //獲取所有的處理結果 for a := 1; a <= 9; a++ { <-results } }
輸出結果:
worker 1 processing job 1
worker 2 processing job 2
worker 3 processing job 3
worker 1 processing job 4
worker 3 processing job 5
worker 2 processing job 6
worker 1 processing job 7
worker 2 processing job 8
worker 3 processing job 9
從中可以看出,多個線程輪流處理了9個任務。
通過這個例子,我們可以學習到:
1、GO中多線程應用開發非常簡單。
2、Channel是不同線程間數據交互的利器。 上面的例子中,主線程向jobs中寫數據,三個工作線程同時從一個Channel中取數據。