| package like_fork_join    import (     "fmt"     "github.com/oklog/ulid/v2" )    const defaultPageSize = 10    type MyForkJoinTask struct {     size int }    // NewMyTask 初始化一个任务 func NewMyTask(pageSize int) *MyForkJoinTask {     var size = defaultPageSize     if pageSize > size {         size = pageSize     }     return &MyForkJoinTask{         size: size,     } }    // Do 执行任务时,传入一个切片 func (t *MyForkJoinTask) Do(numbers []int) int {     JoinCh := make(chan bool, 1)     resultCh := make(chan int, 1)     t.do(numbers, JoinCh, resultCh, ulid.Make().String())     result := <-resultCh     return result }    func (t *MyForkJoinTask) do(numbers []int, joinCh chan bool, resultCh chan int, id string) {     defer func() {         joinCh <- true         close(joinCh)         close(resultCh)     }()     fmt.Printf("id %s numbers %+v\n", id, numbers)     // 任务小于最小颗粒度时,直接执行逻辑(此处是求和),不再拆分,否则进行分治     if len(numbers) <= t.size {         var sum = 0         for _, number := range numbers {             sum += number         }         resultCh <- sum         fmt.Printf("id %s numbers %+v, result %+v\n", id, numbers, sum)         return     } else {         start := 0         end := len(numbers)         middle := (start + end) / 2            // 左         leftJoinCh := make(chan bool, 1)         leftResultCh := make(chan int, 1)         leftId := ulid.Make().String()         go t.do(numbers[start:middle], leftJoinCh, leftResultCh, id+"->left->"+leftId)            // 右         rightJoinCh := make(chan bool, 1)         rightResultCh := make(chan int, 1)         rightId := ulid.Make().String()         go t.do(numbers[middle:], rightJoinCh, rightResultCh, id+"->right->"+rightId)            // 等待左边和右边分治子任务结束         var leftDone, rightDone = false, false         for {             select {             case _, ok := <-leftJoinCh:                 if ok {                     fmt.Printf("left %s join done\n", leftId)                     leftDone = true                 }             case _, ok := <-rightJoinCh:                 if ok {                     fmt.Printf("right %s join done\n", rightId)                     rightDone = true                 }             }             if leftDone && rightDone {                 break             }         }            // 取结果         var (             left            = 0             right           = 0             leftResultDone  = false             rightResultDone = false         )         for {             select {             case l, ok := <-leftResultCh:                 if ok {                     fmt.Printf("id %s numbers %+v, left %s return: %+v\n", id, numbers, leftId, left)                     left = l                     leftResultDone = true                 }             case r, ok := <-rightResultCh:                 if ok {                     fmt.Printf("id %s numbers %+v, right %s return: %+v\n", id, numbers, rightId, right)                     right = r                     rightResultDone = true                 }             }             if leftResultDone && rightResultDone {                 break             }         }            resultCh <- left + right         return     } } |