本人新学Go语言,有个问题一直没找到相关资料,请高手帮忙解答以下。
在Java中,多个线程之间,只有保证了 先行性问题,才能保证不同线程的代码是按预期的先后顺序执行
以下是示例代码:
```go
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学到的线程相关知识不匹配。
``` go
wait goroutine
start goroutine
exit goroutine
all done
```
为什么 1和3 不是随机出现的, 2和4 不是随机出现的。 1和3 是2个不同goroutine,不是应该不能保证哪行代码先执行吗。
亲, 你这个java代码和go的不一样的, go的channel和java的lock实现也不一样, 其实原因我已经说过了, #3 楼的同学应该是理解了.
当前线程或者协程需要等一个点才能放弃对CPU的占用调度给其他的线程或者协程. 而且线程和协程创建了也不会马上启动的, 也是在队列中需要这么个点才能得到CPU的执行机会的.
#4
更多评论
我觉得你啊可能对线程有一些误解.java的线程也不是你想的那样.你得到这个结果一点都不奇怪.
当前执行的线程或者协程是不会马上放弃CPU给其他线程和线程的除非使用了相关的语句和遇到了可以放弃CPU的情况,
你的例子就是这种情况.
#1
package demon.research;
public class BefortTest {
public static Object lock = new Object();
public static void main(String[] args) {
try{
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("start");
synchronized (lock)
{
lock.notifyAll();
}
System.out.println("end");
}
});
t.start();
System.out.println("wait");
synchronized (lock)
{
lock.wait();
}
System.out.println("end all");
}
catch (Exception ex)
{
}
}
}
打印结果出现以下结果:
wait
start
end all
end
所以Java 代码一定有先行性的考虑,你的解释是不正确的。
#2