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())
}
posted @ 2020-03-06 11:31  yangqi7  阅读(224)  评论(0编辑  收藏  举报