package
- 1> 基本复用模块单元
- 2> 代码的package可以和所在的目录不一致
- 3> 同一目录里的Go代码的package要保持一致
package
-
1> 通过go get来获取远程依赖
-
2> 注意代码在GitHub上的组织形式,以适应go get
示例一
示例二
go get 下载的包保存在哪里呢?
一般他会保存在这个目录:$GOPATH/src/import-path , 若你有多个GOPATH(工作区),
则会保存在第一个工作区中。go env 查看go环境
init 方法
- 1> 在main被执行前,所有依赖的package的init方法都会被执行
- 2> 不同包的init函数按照包导入的依赖关系决定执行顺序
- 3> 每个包可以有多个init函数
- 4> 包的每个源文件也可以有多个init函数,这点比较特殊
依赖管理
Go未解决的依赖问题
- 1> 同一环境下,不同项目使用同一包的不同版本
- 2> 无法管理对包的特定版本的依赖
vendor路径
随着Go 1.5 release版本的发布,vendor目录被添加到除了GOPATH和GOROOT之外的依赖目录查找的解决方案
在Go1.6之前,你需要手动的设置环境变量
查找依赖包路径的解决方案如下:
- 1> 当前包下的vendor目录
- 2> 向上级目录查找,直到找到src下的vendor目录
- 3> 在GOPATH下面查找依赖包
- 4> 在GOROOT目录下查找
常用的依赖管理工具
godep https://github.com/tools/godep
glide https://github.com/Masterminds/glide
dep https://github.com/golang/dep
安装glide
- 1> sudo apt install golang-glide
- 2> glide init
- 3> glide install
Thead vs Groutine
//错误写法,想想为什么?
func TestGroutine(t *testing.T) {
for i := 0; i < 10; i++ {
go func() {
fmt.Println(i)
}()
}
time.Sleep(time.Millisecond * 50)
}
/* !< output */
=== RUN TestGroutine
10
10
10
10
10
10
10
10
10
10
--- PASS: TestGroutine (0.05s)
共享内存并发机制
Lock
Lock lock = ...;
lock.lock();
try{
//process (thread-safe)
}catch(Exception ex){
}finally{
lock.unlock();
}
Lock图
WaitGroup
var wg sync.WaitGroup
for i := 0; i < 5000; i++ {
wg.Add(1)
go func() {
defer func() {
wg.Done()
}()
...
}()
}
wg.Wait()
CSP并发机制
Communicating sequential processes
Actor Model
CSP vs Actor
Channel
异步返回
/* !< java */
private static FutureTask<String> service() {
FutureTask<String> task = new FutureTask<String>(()->"Dosomething");
new Thread(task).start();
return task;
}
FutureTask<String> ret = service();
System.out.println("Do something else");
System.out.println(ret.get());
多路选择和超时控制
select
/* !< 多渠道的选择*/
select {
case ret := <-retCh1:
t.Logf("result %s", ret)
case ret := <-retCh2:
t.Logf("result %s", ret)
default:
t.Error("No one returned")
}
/* !< 超时控制 */
select {
case ret := <-retCh:
t.Logf("result %s", ret)
case <-time.After(time.Second * 1):
t.Error("time out")
}
channel的关闭
- 1> 向关闭的channel发送数据,会导致panic
- 2> v, ok <- ch; ok为bool值,true表示正常接受,false表示通道关闭
- 3> 所有的channel接收者都会在channel关闭时,立刻从阻塞等待中返回且上述ok值为false,这个广播机制常被利用,进行向多个订阅者同时发送信号, eg: 退出信号
任务的取消
Context与任务取消
关联任务的取消
Context
- 1> 根Context:通过context.Background()创建
- 2> 子Context: context.WithCancel(parentContext)创建
- ctx, cancel := context.WithCancel(context.Background())
- 3> 当前Context被取消时,基于它的子context都会被取消
- 4> 接收取消通知<-ctx.Done()
并发任务: 仅执行一次
单例模式(懒汉模式,线程安全)
/* !< java */
public class Singleton {
private static Singleton INSTANCE = null;
private Singleton(){}
public static Singleton getlntance() {
if (ISTANCE == null) {
synchronized (Singleton.class) {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
var once sync.Once
var obj *SingletonObj
func GetSingletonObj() *SingletonObj {
once.Do(func() {
fmt.Printl("Create Singleton obj.")
obj = &SingletonObj{}
})
return obj
}
|
请发表评论