前言
你如果熟悉go ,fiber (对于fiber可以简单理解成为轻量级线程)和 channel 就对应go 的goroutines 和channel,在go语言中用法如下:
package main
import "fmt"
func sum(s []int, c chan int) { //方法执行体
sum := 0
for _, v := range s {
sum += v
}
c <- sum // send sum to c
}
func main() { //main 函数
s := []int{7, 2, 8, -9, 4, 0} // 构建一个数组
c := make(chan int) //新建一个channel
go sum(s[:len(s)/2], c) // 新起一个协程,然后在协程中执行方法,相当于new 一个fiber
go sum(s[len(s)/2:], c) // new 一个fiber 。。
x, y := <-c, <-c // receive from c // 通过channel来传递消息
fmt.Println(x, y, x+y)
}
fiber example:
Channel<Object> objectChannel = Channels.newChannel(0); // 0 ,receive() block until send() complete
new Fiber<Void>((SuspendableRunnable) () -> {
// your code
objectChannel.send()
}).inheritThreadLocals().start();
// 简化成java8 functional://todo
什么是channel
channel 用于提供不同fiber之间的交互,保证同一时间只有一个fiber能访问到值。
channel 最主要的两个方法send() and receive(),send() 会阻塞直到结果完成,receive()会阻塞直至send()操作完成。(也正是因为阻塞,所以和fiber(轻量)配合得很好)
BufferChannel ,new channel 的时候指定大小,buffer满的时候会阻塞。
why not use fiber.get()? throw null pointer exception, (how about strand?)
quasar 的fiber提供个get()方法,但在实际交互过程中会存在@suspendable 忘了的情况(交互多的时候比较复杂)
为什么要使用channel
Instead of explicitly using locks to mediate access to shared data, Go encourages the use of channels to pass references to data between goroutines. This approach ensures that only one goroutine has access to the data at a given time. The concept is summarized in the document Effective Go (a must-read for any Go programmer): Do not communicate by sharing memory; instead, share memory by communicating.
比起传统的通过加锁的方式访问变量,fiber通过消息传递的方式来共享变量
channel 更像是queue,通过这种方式来共享消息,这种编程方式的原理的话参考这篇论文CSP
总结
fiber 和channel构建起来的编程模型,简单理解就是,起一个协程(轻量级线程),它们之间的交互通过channel来传递消息。
参考:
share memory by communicate code walk
share memory by communicate blog