| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> 【Go并发基础】 -> 正文阅读 |
|
[Java知识库]【Go并发基础】 |
什么是并发 ? 代码按照顺序执行,即执行完一句才会执行下一句,这样的代码逻辑简单,符合人类的阅读习惯。但是这样是不够的,因为计算机非常强大,比如一款音乐软件,在听音乐的时候想下载歌曲,同一时刻做两件事,在编程中,这就是并发,并发可以让编写的程序在同一时刻做几件事。 进程和线程 ? 讲并发就绕不开线程,不过在介绍线程前,先介绍什么是进程。 ? 进程 ? 在操作系统中,进程是一个非常重要的概念。当启动一个软件时,操作系统会为这个软件创建一个进程,这个进程就是软件的工作空间,它包含了软件运行所需的所有资源,比如内存空间、文件句柄,还有线程。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fXt1v6VA-1639406335171)(/Users/zhangshihao/Library/Application Support/typora-user-images/image-20211213214435023.png)] ? 线程 ? 线程是进程对的执行空间,一个进程可以有多个线程,线程被操作系统调度执行,比如下载一个文件,发送一个消息等。这种多个线程被调度系统同时调度执行的情况,就是多线程并发。 ? 一个程序启动,就会有对应的进程被创建,同时进程也会启动一个线程,这个线程就叫主线程。如果主线程结束,那么整个流程就退出了。有了主线程,就可以从主线程里启动其他线程,也就有了多线程并发。 协程(Goroutine) ? Go语言中没有线程的概念,只有协程,也称为goroutine。相比线程来说,协程更加轻量,一个程序可以随意启动成千上万个goroutine。 ? goroutine被Go Runtime调度,这一点和线程不一样。也即是说,Go语言的并发是由Go自己所调度的,自己决定同事执行多少个goroutine,什么时候执行哪几个。这对于开发者来说是完全透明,只需要在编码的时候告诉Go语言要启动几个goroutine,至于如何调度执行,不用关心。 ? 要启动一个goroutine非常简单,Go语言提供了 go 关键字,相比其他编程语言简化了很多
? 这样就启动了一个goroutine,用来调度fmt.Println()函数。这段代码里有两个goroutine,一个是main函数启动的main goroutine,一个是自己通过go关键字启动的goroutine。 ? go 关键字 紧跟一个方法或者函数,就可以启动一个goroutine,让方法在这启动的goroutine中运行。 Channel ? 如果启动了多个goroutine,他们之间如何通信呢?这就是Go语言提供的 Channel(通道) 要解决的问题。 ? 声明一个 channel ? 在Go语言中,声明一个channel非常简单,使用内置make函数即可
? 定义好chan后就可以使用了,一个chan操作只有两种:发送和接收。
? 小技巧:注意发送和接收的操作符都是**<-**,只不过位置不同。接收的操作符在chan的左侧,发送的操作符在chan的右侧。
? channel有点像在两个goroutine之间架起管道,一个goroutine可以往这个管道发送数据,另一个可以从这个管道接收数据,有点类似队列。 ? 无缓冲channel ? 上述示例中make创建的就是一个无缓冲channel,它的容量是0,不能存储任何数据。所以无缓冲channel只起传输数据的作用,数据并不会在channel中停留。这也意味着,无缓冲channel的发送和接收操作是痛失进行的,它也被称为同步channel。 ? 有缓冲channel ? 有缓冲channel类似一个阻塞对垒,内部的元素先进先出。通过make函数的第二个参数可以指定channel容量的大小,进而创建一个有缓冲channel
? 一个有缓冲channel具备一下特点:
? 因为有缓冲channel类似一个队列,可以获取它的容量和里面元素的个数。
? 小提示:无缓冲channel其实就是一个容量大小为0的channel。比如 make(chan int, 0) ? 关闭 channel ? channel 可以使用内置函数 close 关闭。
? 如果一个channel被关闭了,就不能向里面发送数据了,如果发送的话,会引起panic异常。但是还可以接收channel里的数据,如果channel里面没有数据的话,接收的数据是元素类型的零值。 ? 单向channel ? 有时候,因为特殊的业务需求,比如限制一个channel只可以接收但不能发送,或者限制一个channel只能发送但不能接接收,这种channel被称为单向channel。 ? 单向channel的声明也很简单,只需要在声明的时候带上<- 操作符即可。
? 在函数后者方法的参数中,使用单向channel比较多,这样可以防止一些操作影响了channel.
? select + channel示例 ? 假如我们要下载一个文件,启动了3个goroutine进行下载,并发结果发送到3个channel中。哪个先下载好,就先用哪个channel的结果。 ? 在Go语言中,通难过select语句实现多路复用操作,语句格式如下:
? 整体结构和switch很像,都有case和default,只不过select和case是一个个可以操作的channel。 ? 小提示:多路复用可以简单的理解为,N个channel中,任意一个channel有数据产生,select都可以监听到, 然后执行对应的分支,接收数据并处理。
? 如果这些case中有一个可以执行,select语句会选择该case语句执行,如果同时又多个case可以被执行,则随机选择一个,这样每个case都有平等的被执行的机会。如果一个select没有任何case,那么就会一直等下去。 小结:channel是Go语言并发的基础,在Go语言中,提倡通过通信来共享内存,而不是通过共享内存来通信,其实就是提倡通过channel发送接收消息的方式进行数据通信,而不是通过修改同一个变量。所以在数据流动、传递的场景中要优先使用channel,它是并发安全的,性能也不错。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
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:00:43- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |