Go 典型并发任务
学习-极客时间-Go语言从入门到实战 笔记
单例模式
代码片段举例:
package once
import (
"fmt"
"sync"
"testing"
"unsafe"
)
type Movie struct {
}
var once sync.Once
var SingleInstance *Movie
func GetInstance() *Movie {
once.Do(func() {
fmt.Println("create instance")
SingleInstance = new(Movie)
})
return SingleInstance
}
func TestSingleInstance(t *testing.T) {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
sing := GetInstance()
fmt.Println(unsafe.Pointer(sing))
wg.Done()
}()
}
wg.Wait()
}
仅需任意任务完成
代码片段举例:
package only
import (
"fmt"
"runtime"
"testing"
"time"
)
func runTask(id int) string {
time.Sleep(10 * time.Millisecond)
return fmt.Sprintf("The result is from %d", id)
}
func FirstResponse() string {
numOfRunner := 10
ch := make(chan string, numOfRunner)
//没有指定channel容量,会导致阻塞,channel等待接收者,协程泄漏
//ch := make(chan string)
for i := 0; i < numOfRunner; i++ {
go func(i int) {
ch <- runTask(i)
}(i)
}
return <-ch
}
func TestOnly(t *testing.T) {
t.Log("Before: ", runtime.NumGoroutine())
fmt.Println(FirstResponse())
time.Sleep(time.Second * 1)
t.Log("After: ", runtime.NumGoroutine())
}
所有任务完成
代码片段举例:
package all
import (
"fmt"
"runtime"
"testing"
"time"
)
func runTask(id int) string {
time.Sleep(10 * time.Millisecond)
return fmt.Sprintf("The result is from %d", id)
}
func FirstResponse() string {
numOfRunner := 10
ch := make(chan string, numOfRunner)
//没有指定channel容量,会导致阻塞,channel等待接收者,协程泄漏
//ch := make(chan string)
for i := 0; i < numOfRunner; i++ {
go func(i int) {
ch <- runTask(i)
}(i)
}
res := ""
for j := 0; j < numOfRunner; j++ {
res += <-ch + "\n"
}
return res
}
func TestOnly(t *testing.T) {
t.Log("Before: ", runtime.NumGoroutine())
fmt.Println(FirstResponse())
time.Sleep(time.Second * 1)
t.Log("After: ", runtime.NumGoroutine())
}