本人新学Go语言,有个问题一直没找到相关资料,请高手帮忙解答以下。
在Java中,多个线程之间,只有保证了 先行性问题,才能保证不同线程的代码是按预期的先后顺序执行
以下是示例代码:
package main
import (
"fmt"
)
func main() {
// 构建一个通道
ch := make(chan int)
// 开启一个并发匿名函数
go func() {
fmt.Println("start goroutine") //1
// 通过通道通知main的goroutine
ch <- 0
fmt.Println("exit goroutine") //2
}()
fmt.Println("wait goroutine") //3
// 等待匿名goroutine
<-ch
fmt.Println("all done") //4
}
输出结果: 执行了多次一直是这个结果,与java学到的线程相关知识不匹配。
wait goroutine
start goroutine
exit goroutine
all done
为什么 1和3 不是随机出现的, 2和4 不是随机出现的。 1和3 是2个不同goroutine,不是应该不能保证哪行代码先执行吗。
有疑问加站长微信联系(非本文作者)

我觉得你啊可能对线程有一些误解.java的线程也不是你想的那样.你得到这个结果一点都不奇怪. 当前执行的线程或者协程是不会马上放弃CPU给其他线程和线程的除非使用了相关的语句和遇到了可以放弃CPU的情况, 你的例子就是这种情况.
package demon.research;
public class BefortTest {
}
打印结果出现以下结果:
wait start end all end
所以Java 代码一定有先行性的考虑,你的解释是不正确的。
理想情况下是1和3先后顺序随机。实际情况是启动一个goroutine或Thread需要消耗资源,所以一般都是 3 早于 1 先打印出来。 还有就是 go 的输出顺序是 3124 Java也是 3124。你又说不一样,
亲, 你这个java代码和go的不一样的, go的channel和java的lock实现也不一样, 其实原因我已经说过了, #3 楼的同学应该是理解了. 当前线程或者协程需要等一个点才能放弃对CPU的占用调度给其他的线程或者协程. 而且线程和协程创建了也不会马上启动的, 也是在队列中需要这么个点才能得到CPU的执行机会的.
如果你需要lock,就直接用lock
chan不是用来解决这个问题的……
@zzustu 问题已知晓。我本地调试了很多遍,没有出现乱序,让其他人调试,出现了乱序,是预期的,所以go routine 也是不能保证顺序。我本意也是go 应该出现乱序。
@jarlyyn 不是想用了lock,只是本地测试的时候,没有出现乱序,所以有些疑问。我的理解是go 应该出现乱序。