「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」
生命不息,学习不止
题外话
大年初五啦,昨晚大家有没有看东奥的开幕式啊,不得不说,真滴好看呀,五环从冰里出来的时候我真滴惊呆了,爆赞,雪融融真滴可爱,等我有钱了,我到时候也去现场看
废话不多说,上货
LeetcCode-1114
1114. 按序打印
题目如下:
给你一个类:
public class Foo {
public void first() { print("first"); }
public void second() { print("second"); }
public void third() { print("third"); }
}
三个不同的线程 A、B、C 将会共用一个 Foo 实例。
线程 A 将会调用 first() 方法 线程 B 将会调用 second() 方法 线程 C 将会调用 third() 方法 请设计修改程序,以确保 second() 方法在 first() 方法之后被执行,third() 方法在 second() 方法之后被执行。
示例如下
示例 1:
输入:nums = [1,2,3] 输出:"firstsecondthird" 解释: 有三个线程会被异步启动。输入 [1,2,3] 表示线程 A 将会调用 first() 方法,线程 B 将会调用 second() 方法,线程 C 将会调用 third() 方法。正确的输出是 "firstsecondthird"。
示例 2:
输入:nums = [1,3,2] 输出:"firstsecondthird" 解释: 输入 [1,3,2] 表示线程 A 将会调用 first() 方法,线程 B 将会调用 third() 方法,线程 C 将会调用 second() 方法。正确的输出是 "firstsecondthird"。
算法实现思路
这是一道简单难度的多线程题,不是很难,主要考察的是对于多线程开发的一个熟悉程度。
我们都知道多线程并发情况下,顺序打印时无序的,多少次运行就可能有多少次情况,在java的多线程情况下,我们一般会使用阻塞,挂起或是计数器的方式让多线程中的某单一线程停止。
但go语言是非常适合并发场景的开发语言,我们可以采用通道的方式来实现并发。
go实现算法
var secondChan = make(chan struct{})
var thirdChan = make(chan struct{})
var mainChan = make(chan struct{})
func first() {
fmt.Print("first")
secondChan <- struct{}{}
}
func second() {
<-secondChan
fmt.Print("second")
thirdChan <- struct{}{}
close(secondChan)
}
func third() {
<-thirdChan
fmt.Print("third")
mainChan <- struct{}{}
close(thirdChan)
}
func main() {
funcMap := map[int]func(){1: first, 2: second, 3: third}
for _, v := range funcMap {
go v()
}
<-mainChan
这道题不支持go,所以我就简单的写了一个小demo,我猜可能是用go写太简单,哈哈哈哈
go的并发
go设计的初衷中有一部分就是为了更好的适用于并发场景,所以go的并发开启相比于其他语言是比较简单的
我们只需要使用go 关键字即可开启一个goroutine用于并发。
goroutine 是轻量级线程。开启方式如下
go func_name (参数1,参数2,……)
举个例子
fo thread(a,b,c)
一个程序中可以开启多个goroutine,所有的goroutine共享同一个地址空间。
go的通道
go的通道是用来在goroutine线程之间传递数据的一种数据结构,通过操作符<-指定通道的方向,发送或接收。
默认情况下为双向通道(未指定方向)
通道的声明也很简单,算法的实现中也有所体现,如下
var secondChan = make(chan struct{})
var thirdChan = make(chan struct{})
var mainChan = make(chan struct{})
通过内置函数声明,声明的格式入下
var chan_name = make(chan type)
算法的实现中type格式空的结构体,因为不需要传递具体的数据,只需要形成顺序
struct {}
struct {}是一个无元素的结构体类型,通常在没有信息存储时使用。优点是大小为0,不需要内存来存储struct {}类型的值。
struct {} {}
struct {} {}是一个复合字面量,它构造了一个struct {}类型的值,该值也是空。
你以为结束了
小问题: 如何构建一个带缓冲区的通道?如何去遍历或是关闭通道?为什么通道能让线程顺序执行?
下一篇就讲,敬请期待
大家看完发现有什么错误,写在下面吧!跟我黑虎阿福比划比划!