golangスレッドの安全なSet構造を実現
6106 ワード
同時アクセスのサポート
package main
import (
"sync"
"fmt"
)
type Set struct {
m map[interface{}]bool
sync.RWMutex
}
func New() *Set {
return &Set{
m :map[interface{}]bool{},
}
}
func (s *Set) Add (item interface{}) {
//
s.Lock()
defer s.Unlock()
s.m[item] = true
}
func (s *Set) Remove (item interface{}) {
//
s.Lock()
defer s.Unlock()
delete(s.m, item)
}
func (s *Set) Has (item interface{}) bool {
//
s.RLock()
defer s.RUnlock()
_, ok := s.m[item]
return ok
}
func (s *Set) List() []interface{} {
//
s.RLock()
defer s.RUnlock()
var outList []interface{}
for value := range s.m {
outList = append(outList, value)
}
return outList
}
func (s *Set) Len() int {
return len(s.List())
}
func (s *Set) Clear() {
s.Lock()
defer s.Unlock()
s.m = map[interface{}]bool{}
}
func (s *Set) IsEmpty() bool {
if s.Len() == 0 {
return true
}
return false
}
func main () {
s := New()
wait := sync.WaitGroup{}
go func() {
wait.Add(1)
defer wait.Done()
s.Add(1)
s.Add("2")
s.Add("3")
}()
go func() {
wait.Add(1)
defer wait.Done()
s.Add(1)
s.Add("2")
s.Add("3")
}()
go func() {
wait.Add(1)
defer wait.Done()
s.Add(3.1415926)
//fmt.Println(s.List())
s.Remove("2")
//fmt.Println(s.List())
}()
go func() {
wait.Add(1)
defer wait.Done()
if s.Has("2") {
fmt.Println("2 exist")
} else {
fmt.Println("2 not exist")
}
}()
go func() {
wait.Add(1)
defer wait.Done()
if s.Has(3.1415926) {
fmt.Println("3.1415926 exist")
} else {
fmt.Println("3.1415926 not exist")
}
}()
for i:= 99; i< 999 ;i++ {
s.Add(i)
}
fmt.Println("main gorotue :")
fmt.Println("clear before ")
fmt.Println("len == ", s.Len())
fmt.Println("Is empty:", s.IsEmpty())
s.Clear()
fmt.Println("clear after")
fmt.Println("is empty:", s.IsEmpty())
fmt.Println("len == ", s.Len())
wait.Wait()
}