设计模式2:单例模式
单例模式保证一个类仅有一个实例,并提供一个全局访问点。
应用场景如:
- 配置文件管理器:在一个应用程序中,通常会有一些全局的配置信息需要被读取和管理,这些配置信息只需要被读取一次,而且希望能够在整个应用程序中共享。这时候,单例模式就非常适合用来管理这些配置信息。
- 日志记录器:在一个应用程序中,通常需要记录一些日志信息,这些日志信息需要被记录到同一个文件中,而且希望能够在整个应用程序中共享。这时候,单例模式就非常适合用来管理这些日志信息。
- 数据库连接池:在一个应用程序中,通常需要连接到数据库来读取和写入数据,这些数据库连接需要被管理和共享。这时候,单例模式就非常适合用来管理这些数据库连接。
- 线程池:在一个应用程序中,通常需要创建和管理多个线程来处理任务,而且希望能够在整个应用程序中共享这些线程。这时候,单例模式就非常适合用来管理这些线程。
示例
示例1
package main
import (
"fmt"
"sync"
)
type singleton struct{}
var instance *singleton
var once sync.Once
func GetInstance() *singleton {
once.Do(func() {
instance = &singleton{}
})
return instance
}
func main() {
instance1 := GetInstance()
instance2 := GetInstance()
if instance1 != instance2 {
fmt.Println("Instances are not the same!")
} else {
fmt.Println("Instances are the same!")
}
}
示例2
package main
import (
"fmt"
"sync"
)
type ThreadPool struct {
maxWorkers int
queue chan func()
once sync.Once
}
var instance *ThreadPool
func GetInstance() *ThreadPool {
if instance == nil {
instance = &ThreadPool{}
instance.once.Do(func() {
instance.maxWorkers = 10
instance.queue = make(chan func(), 100)
for i := 0; i < instance.maxWorkers; i++ {
go instance.worker()
}
})
}
return instance
}
func (tp *ThreadPool) worker() {
for f := range tp.queue {
f()
}
}
func (tp *ThreadPool) AddTask(f func()) {
tp.queue <- f
}
func main() {
tp := GetInstance()
for i := 0; i < 100; i++ {
tp.AddTask(func() {
fmt.Println("Hello, world!")
})
}
}