Go中自带的sync包中包含了一些可以实现锁功能的工具。常用的有sync.Mutex,sync.RWMutex,sync.WaitGroup,sync.Once。另外顺便说一下,查看源码发现sync包中锁的实现都是基于CAP(Java8中也有很多地方用了CAP,这里东西还是值得了解一下的)。
1. sync.Mutex与sync.RWMutex
看名字就知道一个是普通锁,一个是读写锁。用起来都十分简单。
对于任何 sync.Mutex
或 sync.RWMutex
类型的变量 l
以及 n < m ,对 l.Unlock()
的第 n 次调用在对 l.Lock()
的第 m 次调用返回前发生。
import ("sync")
type Person struct {
sync.Mutex //sync.Mutex或者sync.RWMutex是可以内嵌到结构体中的
Name string
}
func (p *Person) SetName(name string) {
p.Lock() //这里就可以直接调用Lock方法
p.Name = name
p.Unlock()
}
var l sync.Mutex
func (p *Person) SetName1(name string) {
l.Lock() //这里是用的变量 l 的Lock方法
p.Name = name
l.Unlock()
}
2. sync.Once
这个对象保证方法只被执行一次,在实现单例模式时很有用。查看源码就知道其实也是用的双重检查模式,只不过因为Go支持面向函数编程,可以把单例的生成方法最为参数传给sync.Once.
3.sync.WaitGroup
可以做到类似于Java中Thead.join的功能,就是阻塞直到某些goroutine执行完成。
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func caculate1() {
fmt.Println("计算1完成")
wg.Done() //完成任务就调用Done
}
func caculate2() {
fmt.Println("计算2完成")
wg.Done() //完成任务就调用Done
}
func main() {
wg.Add(2) //总共有两个任务,这里需要Add 2
go caculate1()
go caculate2()
wg.Wait() //等待所有任务完成
fmt.Println("最终完成")
}
Go中单元测试非常简单。普通的Go的源码文件都是已".go"作为后缀,如果一个Go文件以"_test.go"作为后缀,那么这就是一个单元测试(在Go源码里能看到很多这样的文件。)
这个文件很简单,首先,该文件必须与被测试代码处于同一个文件夹中个,其次它的package声明必须以被测试代码一致;接着import进 "testing"包;再下来就是编写测试方法了,这个方法的方法名必须以“Test”开头,并且参数类型是 *testing.T。
package cache
import (
"testing"
)
func TestSetAndGet(t *testing.T) { //方法名前缀是Test,参数类型是*testing.T
if ....... {
t.FailNow()
}
}
运行单元测试也非常简单,在LiteIDE中用快捷键“Ctrl + T”就行了;在命令行是使用 go test -v 包目录 就可以了
1. os
os.Args 入口参数,就是Java的main函数的那一坨参数
os.Open / os.OpenFile
*os.File 文件句柄,这个类本身就实现了io.ReadWriter接口
2. io 和 io/ioutil
io相关的接口和工具
3. bytes
bytes.Buffer 是一个实现了io.ReadWriter的切片
bytes.ToLower / ToUpper 大小写装换,不要以为Go中string真是个string,本质上go还是把字符串当字节切片处理的。
http://4.net和net/http
网络相关的包。在Linux上,底层是poll模型,想高性能用epoll或者kqueue,对不起,自己造一个轮子吧