I've implemented singleton pattern using the code below:
// Singleton definition.
type Singleton struct {
Name string
}
var (
instance *Singleton
)
// NewSingleton return singleton instance.
func NewSingleton() *Singleton {
if instance == nil {
instance = &Singleton{Name: "singleton"}
}
return instance
}
I knew that it's not the proper way to do that because multiple goroutines maybe return the different instances.
And now I just want to prove that using go test.
func TestParallelSingleton(t *testing.T) {
count := 10
instances := make([]*Singleton, count)
signal := make(chan struct{})
// New singletons with multiple goroutines.
for i := 0; i < count; i++ {
go func(c int) {
instances[c] = NewSingleton()
signal <- struct{}{}
}(i)
}
// Wait for all goroutines to complete.
for i := 0; i < count; i++ {
<-signal
}
// Check all the singletons are equal.
for i := 1; i < count; i++ {
// t.Log(instances[i].Name)
if instances[i] != instances[i-1] {
t.Fatalf("Singleton instances %d and %d are not equal", i-1, i)
}
}
t.Log("All singleton instances are equal")
}
func TestParallelSingleton1(t *testing.T) {
count := 10
instances := make([]*Singleton, count)
for i := 0; i < count; i++ {
i := i
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
t.Parallel()
instances[i] = NewSingleton()
t.Logf("%p, %v", instances[i], instances[i])
})
}
}
But the result show that all the goroutines return the same instance with the same address which is strange.
I also increase the goroutines to 10,000 but the results are the same.
So is there something wrong with my code and what should I do?
Thanks in advance.
Aucun commentaire:
Enregistrer un commentaire