同步/异步和阻塞/非阻塞学习笔记


概述

看了几篇同步,异步,阻塞和非阻塞的文章,感觉还是云里雾里的。本文结合自己的理解写几个例子加深印象,可能理解有误。大佬们可以帮忙批评指正。

个人理解同步/异步,阻塞/非阻塞是站在不同角度看的概念。

同步/异步:站在被调用方视角看,同步会执行调用方的请求,请求结束后返回执行结果给调用方。异步会先响应调用方请求,在执行调用方请求,最后给结果。

阻塞/非阻塞:站在调用方视角看,阻塞会等待被调用方响应,在等待期间啥事也不干。非阻塞在等待被调用方响应期间可以干别的事。

示例

本文以买咖啡为例介绍同步,异步,阻塞和非阻塞的几种情况。

同步阻塞

type Customer struct{}  
  
func (c *Customer) BuyCoffee() {  
    coffee, ok := worker.MakeCoffee()  
    if !ok {  
       fmt.Println("make coffee failed")  
    }  
    fmt.Println("get my coffee", coffee.Name)  
}  
  
type Coffee struct {  
    Name string  
}  
  
type Worker struct{}  
  
var worker Worker  
  
func (w *Worker) MakeCoffee() (coffee *Coffee, ok bool) {  
    fmt.Println("start make coffee")  
    time.Sleep(1 * time.Second)  
    fmt.Println("make coffee finish")  
  
    return &Coffee{Name: "latte"}, true  
}  
  
func main() {   
    hxia := &Customer{}  
    hxia.BuyCoffee()  
}

同步阻塞,当用户买咖啡时,咖啡师开始做用户的这一杯咖啡,用户等咖啡做好。咖啡师做好后把咖啡给用户,用户拿到咖啡。这是同步逻辑,可以看到同步阻塞,当咖啡师做咖啡时,用户啥也不干,效率较低。

异步阻塞

type Customer struct{}  
  
func (c *Customer) BuyCoffee() {  
    go worker.MakeCoffee()  
  
    for coffeeWithResult := range coffeec {  
       if !coffeeWithResult.Result {  
          fmt.Println("make coffee failed")  
       }  
       if coffeeWithResult.Coffee != nil {  
          fmt.Println("get my coffee", coffeeWithResult.Coffee.Name)  
       }  
    }  
}  
  
type Coffee struct {  
    Name string  
}  
  
type Worker struct{}  
  
var worker Worker  
  
func (w *Worker) Do() {  
    fmt.Println("start make coffee")  
    time.Sleep(1 * time.Second)  
    fmt.Println("make coffee finish")  
}  
  
type CoffeeWithResult struct {  
    Coffee *Coffee  
    Result bool  
}  
  
var coffeec = make(chan CoffeeWithResult)  
  
func (w *Worker) MakeCoffee() {  
    fmt.Println("response to customer that I'm start to make your coffee")  
    coffeec <- CoffeeWithResult{Coffee: nil, Result: true}  
  
    var wg sync.WaitGroup  
    wg.Add(1)  
    go func() {  
       defer wg.Done()  
       w.Do()  
    }()  
    wg.Wait()  
  
    coffeec <- CoffeeWithResult{Coffee: &Coffee{Name: "latte"}, Result: true}  
    close(coffeec)  
}  
  
func main() {   
    hxia := &Customer{}  
    hxia.BuyCoffee()  
}

异步阻塞,当用户买咖啡时,咖啡师先告诉用户我在做咖啡了,用户还是等咖啡做好。咖啡师告诉用户之后,才继续做咖啡。异步对咖啡师友好,如果咖啡师在做咖啡的间隙还能做别的,咖啡师可以去做别的事情(咖啡师可以同时做好几杯咖啡,而不是用户这一杯)。对于咖啡师来说效率提高了。

同步非阻塞

type Customer struct{}  
  
func (c *Customer) BuyCoffee() {  
    go worker.MakeCoffee()  
  
    for {  
       select {  
       case CoffeeWithResult, ok := <-coffeec:  
          if !ok {  
             return  
          }  
          if !CoffeeWithResult.Result {  
             fmt.Println("make my coffee failed")  
             break  
          }  
          if CoffeeWithResult.Coffee != nil {  
             fmt.Println("get my coffee", CoffeeWithResult.Coffee.Name)  
          }  
       default:  
          fmt.Println("do something")  
          time.Sleep(100 * time.Millisecond)  
       }  
    }  
}  
  
type Coffee struct {  
    Name string  
}  
  
type Worker struct{}  
  
var worker Worker  
  
type CoffeeWithResult struct {  
    Coffee *Coffee  
    Result bool  
}  
  
var coffeec = make(chan CoffeeWithResult)  
  
func (w *Worker) MakeCoffee() {  
    fmt.Println("start make coffee")  
    time.Sleep(1 * time.Second)  
    fmt.Println("make coffee finish")  
    coffeec <- CoffeeWithResult{Coffee: &Coffee{Name: "latte"}, Result: true}  
    close(coffeec)
}
  
func main() {  
    hxia := &Customer{}  
    hxia.BuyCoffee()  
}

同步非阻塞,当用户买咖啡时,咖啡师开始做这一杯咖啡,用户在等咖啡期间可以做别的事情(玩玩手机,回复信息等等)。咖啡师做好咖啡后告诉用户,用户再去取咖啡。对于用户来说效率提高了,不是在那干等。

异步非阻塞

type Customer struct{}  
  
func (c *Customer) BuyCoffee() {  
    go worker.MakeCoffee()  
  
    for {  
       select {  
       case CoffeeWithResult, ok := <-coffeec:  
          if !ok {  
             return  
          }  
          if !CoffeeWithResult.Result {  
             fmt.Println("make my coffee failed")  
             break  
          }  
          if CoffeeWithResult.Coffee != nil {  
             fmt.Println("get my coffee", CoffeeWithResult.Coffee.Name)  
          }  
       default:  
          fmt.Println("do something")  
          time.Sleep(100 * time.Millisecond)  
       }  
    }  
}  
  
type Coffee struct {  
    Name string  
}  
  
type Worker struct{}  
  
var worker Worker  
  
func (w *Worker) Do() {  
    fmt.Println("start make coffee")  
    time.Sleep(1 * time.Second)  
    fmt.Println("make coffee finish")  
}  
  
type CoffeeWithResult struct {  
    Coffee *Coffee  
    Result bool  
}  
  
var coffeec = make(chan CoffeeWithResult)  
  
func (w *Worker) MakeCoffee() {  
    fmt.Println("response to customer that I'm start to make your coffee")  
    coffeec <- CoffeeWithResult{Coffee: nil, Result: true}  
  
    var wg sync.WaitGroup  
    wg.Add(1)  
    go func() {  
       defer wg.Done()  
       w.Do()  
    }()  
    wg.Wait()  
  
    coffeec <- CoffeeWithResult{Coffee: &Coffee{Name: "latte"}, Result: true}  
    close(coffeec)  
}  
  
func main() {  
    hxia := &Customer{}  
    hxia.BuyCoffee()  
}

异步非阻塞,有了前面的介绍,我们应该知道,异步的话咖啡师可以并行做几杯咖啡,而不是只做用户这一杯,用户在等咖啡期间也可以干自己的事,而不是只等自己的咖啡。对于用户和咖啡师效率都提高了。

参考文章


posted @ 2025-11-13 11:58  胡云Troy  阅读(16)  评论(0)    收藏  举报