IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 送了两趟外卖,我想明白了Goroutine + Channel -> 正文阅读

[Java知识库]送了两趟外卖,我想明白了Goroutine + Channel

goroutine 和 channel 是 Golang 的并发的两把利剑,想要掌握 Golang,需要学好这两把利剑。还好这并不难,我送了两趟外卖就想明白了🐶。

简介

Goroutine 被称为Go协程,可以通过 go 关键词创建一个协程。

go func() {
    // do 
}()

Channel 被称为通道,通过 make 关键创建。

ch := make(chan T)
// or
ch := make(chan T, n)

Channel 分为无缓冲和有缓冲两种,有缓冲 channel 可以通过 make 的第二个参数设置缓冲大小。

Goroutine + 无缓冲 Channel

在并发中,多个 Goroutine 之间相互通信,需要借助 channel 来实现。

下面示例代码中,启动两个协程,分别代表“点外卖的你”和“送外买的我”,我们分别在各自的协程中忙碌着自己的事情。我们通过 channel (门)进行通信。

对于一个无缓冲的 channel 来说,我把消息(鸡腿外卖)给你需要通过一个无缓冲的 channel (门)。无缓冲的 channel 就意味着,我必需亲手把鸡腿送到你的手上,而不能把鸡腿挂到门把手上就去忙其他事儿

ch <- food:此时我阻塞在这里,在你磨磨唧唧开门前,我都要在这里等待。

一段时间后,你忙完了其他事情,来门口拿鸡腿food := <- ch

我把鸡腿亲手交给你之后,便可以不再阻塞,我可以继续送其他订单。你拿到外卖,开始吃鸡。

如果有一次,你饿的不行,恰好忙完了手头的所有事儿,就来门口等外卖。当我外卖没送到前,你需要在这里阻塞,等待外卖。只有我敲门把鸡腿亲手递给你,你才能开吃。

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan string)

    go func() {
        who := "外卖小哥我:"
        food := "鸡腿"
        fmt.Println(who, "送餐中……2s")
        time.Sleep(time.Second * 2)
        fmt.Println(who, "已送餐到门口,等待顾客开门取餐")
        ch <- food
        fmt.Println(who, "订单已送达,开始送其他单")
    }()

    go func() {
        who := "你:"
        fmt.Println(who, "等待外卖……")
        time.Sleep(time.Second * 3)
        fmt.Println(who, "磨磨唧唧开门中……3s")
        food := <- ch
        fmt.Println(who, "拿到", food, "开吃!")
    }()

    time.Sleep(time.Second * 5)
}

Goroutine + 缓冲 Channel

无缓冲的 channel,迫使我阻塞,影响了我送外卖的效率。我决定利用缓冲容量为1的channel与你通信,提高我的送外卖效率。

于是,当我来到你的门口,我就可以把鸡腿挂到门把手上(ch <- food),这不是是我阻塞,然后我可以去送其他订单。当你忙完事情可以随时开门取餐(food := <- ch)。这样,我和你两个人都不用因为别人的事情相互等待。并行的我和你,都在按部就班的执行自己的时候,却能通过 channel 共享数据。这就是缓冲 channel。

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan string, 1)

    go func() {
        who := "外卖小哥我:"
        food := "鸡腿"
        fmt.Println(who, "送餐中……2s")
        time.Sleep(time.Second * 2)
        fmt.Println(who, "已送餐到门口,餐挂门把手了(缓冲区)")
        ch <- food
        fmt.Println(who, "订单已送达,开始送其他单")
    }()

    go func() {
        who := "你:"
        fmt.Println(who, "等待外卖……")
        time.Sleep(time.Second * 3)
        fmt.Println(who, "磨磨唧唧开门中……3s")
        food := <- ch
        fmt.Println(who, "拿到", food, "开吃!")
    }()

    time.Sleep(time.Second * 5)
}

总结

无缓冲 channel 就是需要我把鸡腿亲手交到你的手上,缓冲 channel 就是我可以把鸡腿挂到门把手上,等待你需要时来取。

看到这里你已经明白了 Goroutine + Channel ,接下来就留一个思考题,相信听懂了的你,一定能做出来~

思考题:请执行下面输出结果

func main() {
    ch := make(chan string, 1)

    go func() {
        who := "送完外卖的我:"
        time.Sleep(time.Second)
        fmt.Println(who, "writing……1 hour")
        ch <- "文章"
    }()

    go func() {
        who := "你:"
        fmt.Println(who, "摸鱼……")
        read := <- ch
        fmt.Println(who, "获得阅读", read, ", 并点赞")
    }()

    time.Sleep(time.Second * 5)
}

文章来自 送了两趟外卖,我想明白了Goroutine + Channel 本文由博客一文多发平台 OpenWrite 发布!

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-11 15:35:19  更:2021-12-11 15:36:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:07:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码