go源码阅读-sync.waitgroup
前言sync.waitgroup 是一种用于同步的工具,它允许一组goroutine在继续执行之前等待其他goroutine完成。WaitGroup.Done方法和Wait方法共同工作来实现这种同步。
WaitGroup.Add方法用于初始化计数器,表示需要等待的goroutine的数量。
每个goroutine完成时调用WaitGroup.Done方法,减少计数器。
WaitGroup.Wait方法阻塞调用它的goroutine,直到WaitGroup维护的计数器为零。(state字段)官方文档中有这样一段注释:In the terminology of the Go memory model, a call to WaitGroup.Done “synchronizes before” the return of any Wait call that it unblocks.synchronizes before这个术语是Go内存模型(Go Memory Model, GMM)的一部分,它描述了程序中不同部分之间的内存可见性。在Go内存模型中,如果一个操作synchronizes ...
go源码阅读-sync.Pool
前言接上文go源码阅读-sync.Once继续来看sync包下的Pool。简而言之,sync.Pool是一组可以单独保存和检索的临时对象。
存储在池中的任何项目都可能在任何时候被自动移除,且不会通知。如果发生这种情况时池持有唯一的引用,则该项目可能会被释放。
Pool是并发安全的,可以被多个协程同时使用
Pool的目的是缓存已分配但未使用的项目以供后续重用,减轻垃圾回收器的压力
池的一个良好使用示例是在fmt包中,它维护了一个动态大小的临时输出缓冲区存储。该存储在负载下(当许多goroutine积极打印时)会扩展,并在空闲时缩小
与sync.Once类似,sync.Pool不允许拷贝
使用1. 声明对象池如下代码调用sync.Pool时传入func()作为New, 在对象池中没有对象时将会调用New创建对象。
12345678910type Student struct { Name string Age int}var studentPool = sync.Pool{ New: func() interface{} { ...
go源码阅读-sync.Once
go语言基础库sync中提供了基本的同步原语,包括Once和waitGroup等。注意,sync包中定义的类型均不可被复制。
sync.Oncesync.Once包中仅对外暴露了一个方法,即Do方法,该方法仅接受一个f func(){} 作为参数,保障当且仅当第一次调用once市里的Do方法时,才会执行f func()。如果多次调用 once.Do(f), 仅有第一次调用时才会调用f。常用于单例模式,例如初始化配置、保持数据库连接等
使用方式如下样例中,使用sync.Once读取配置文件防止多次调用。
123456789101112131415161718192021222324252627282930313233package paralleltype Config struct { Server string Port int64}var ( once sync.Once config *Config)func ReadConfig() *Config { once.Do(func() { var err err ...
juc之CountDownLatch
CountDownLatch是什么?CountDownLatch 是一种同步辅助工具,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。通过指定 count 来初始化 CountDownLatch,await()方法将阻塞直到线程使用 countDown() 方法减少count 直至为0时释放 所有等待的线程,以及被阻塞的方法将被立即返回。另外, CountDownLatch 的 count 无法被重置。 如果需要重置 count, 可使用 CyclicBarrier。
CountDownLatch 使用场景场景一: 某个线程等待N个线程执行完成后执行
count=N:一个线程等待 其余N个线程完成操作,或者一个线程完成N次操作。
CountDownLatch 初始值为N
等待的线程执行 await 操作,使得当前线程被阻塞(使用LockSupport阻塞) [这里也可以在main中阻塞]
每个线程执行完毕后,调用countDown()
当计数器值变为0,被阻塞的县城会被唤醒,执行待执行的动作。
12345678910111213141516import j ...