编程语言
首页 > 编程语言> > 学习中记录差异—java和golang并发的不同点

学习中记录差异—java和golang并发的不同点

作者:互联网

本文打算从三点进行阐述

1.java的并发机制原理
2.golang的并发机制原理
3.两者有什么不同,导致了什么问题

1.java的并发机制原理

a.有点需要理解的东西
CPU访问存储的方式——多级存储;
CPU执行指令的方式——乱序

下文找到对应的例子体会===会更加清楚

b.感谢老铁的科普(我觉得讲的挺好的文章)
https://blog.csdn.net/fct2001140269/article/details/82634240

c.总结:
存储访问引起的不一致性+CPU为了提高效率引入的并行机制就是并发程序设计的困难,这两个问题结合在一起就是“Memory barrier”(内存屏障、内存栅栏),这不是Java独有的,在任何编程语言中都会存在这个问题,除非你的CPU不是多级存储、没有流水线。

2.golang的并发机制原理

Go 提供了一个更加优雅的解决方案,那就是 channel。
channel 应用

Go 与 Java 的一个很大的区别就是并发模型不同,Go 采用的是 CSP(Communicating sequential processes) 模型;用 Go 官方的说法:

Do not communicate by sharing memory; instead, share memory by communicating.

翻译过来就是:不用使用共享内存来通信,而是用通信来共享内存。

而这里所提到的通信,在 Go 里就是指代的 channel。

a.对于java 不一样的多级存储,go用的是通道channel

自己写了个demo体会一下:

package main

import (
	"fmt"
	"time"
)

//main()相当于是主协程
func main() {
	//匿名子协程
	go func() {
		i := 0
		for {
			if i < 5 {
				i++
				fmt.Println("子协程 i=", i)
				time.Sleep(1 * time.Second)
			}

		}
	}()
	i := 0
	for {
		i++
		fmt.Println("主协程 i=", i)
		time.Sleep(1 * time.Second)
		//主协程第二次后退出
		if i == 10 {
			break
		}
	}
}

这里面主协程的i就会影响到子协程的资源,相同的情况下Java是不会相互影响的

b.golang的channel原理
在这里插入图片描述

在第 1 步,两个 goroutine 都到达通道,但哪个都没有开始执行发送或者接收。
在第 2 步,左侧的 goroutine 将它的手伸进了通道,这模拟了向通道发送数据的行为。这时,这个 goroutine 会在通道中被锁住,直到交换完成。
在第 3 步,右侧的 goroutine 将它的手放入通道,这模拟了从通道里接收数据。这个 goroutine 一样也会在通道中被锁住,直到交换完成。
在第 4 步和第 5 步,进行交换。
在第 6 步,两个 goroutine 都将它们的手从通道里拿出来,这模拟了被锁住的 goroutine 得到释放。两个 goroutine 现在都可以去做别的事情了。

3.两者有什么不同,导致了什么问题

感谢博主的图:https://blog.csdn.net/weixin_39189376/article/details/106179662

标签:main,java,goroutine,golang,并发,线程,go,不同点
来源: https://blog.csdn.net/weixin_48962061/article/details/120163361