getInstance()<\/strong>.<\/p>\n\n\n\n In GO we have goroutines. Hence the singleton struct should return the same instance whenever multiple goroutines are trying to access that instance. It is very easy to get a singleton design pattern wrong. The below code illustrates the right way to create a singleton object. <\/p>\n\n\n\n
var lock = &sync.Mutex{}\n\ntype single struct {\n}\n\nvar singleInstance *single\n\nfunc getInstance() *single {\n if singleInstance == nil {\n lock.Lock()\n defer lock.Unlock()\n if singleInstance == nil {\n fmt.Println(\"Creting Single Instance Now\")\n singleInstance = &single{}\n } else {\n fmt.Println(\"Single Instance already created-1\")\n }\n } else {\n fmt.Println(\"Single Instance already created-2\")\n }\n return singleInstance\n}<\/code><\/pre>\n\n\n\nAbove code ensures that only one instance of the single struct is created. Some point worth noting. <\/p>\n\n\n\n
There is a check at the start for nil singleInstance<\/strong>. This is to prevent the expensive lock operations every time getinstance()<\/strong> method is called. If this check fails then it means that singleInstance<\/strong> is already created<\/li>The singleInstance<\/strong> is created inside the lock.<\/li>There is another check for nil singleIinstance<\/strong> after the lock is acquired. This is to make sure that if more than one goroutine bypass the first check then only one goroutine is able to create the singleton instance otherwise each of the goroutine will create its own instance of the single<\/strong> struct.<\/li><\/ol>\n\n\n\nHere is the full code<\/p>\n\n\n\n
single.go<\/strong><\/p>\n\n\n\npackage main\n\nimport (\n \"fmt\"\n \"sync\"\n)\n\nvar lock = &sync.Mutex{}\n\ntype single struct {\n}\n\nvar singleInstance *single\n\nfunc getInstance() *single {\n if singleInstance == nil {\n lock.Lock()\n defer lock.Unlock()\n if singleInstance == nil {\n fmt.Println(\"Creting Single Instance Now\")\n singleInstance = &single{}\n } else {\n fmt.Println(\"Single Instance already created-1\")\n }\n } else {\n fmt.Println(\"Single Instance already created-2\")\n }\n return singleInstance\n}<\/code><\/pre>\n\n\n\nmain.go<\/strong><\/p>\n\n\n\npackage main\n\nimport (\n \"fmt\"\n)\n\nfunc main() {\n for i := 0; i < 100; i++ {\n go getInstance()\n }\n \/\/ Scanln is similar to Scan, but stops scanning at a newline and\n \/\/ after the final item there must be a newline or EOF.\n fmt.Scanln()\n}<\/code><\/pre>\n\n\n\nOutput:<\/strong><\/p>\n\n\n\nCreting Single Instance Now\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-2\nSingle Instance already created-2\nSingle Instance already created-2\nSingle Instance already created-2\nSingle Instance already created-2\nSingle Instance already created-2\nSingle Instance already created-2\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-2\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1\nSingle Instance already created-1<\/code><\/pre>\n\n\n\nNote:<\/strong><\/p>\n\n\n\nThere is one output of \"Creating Single Instance Now\" <\/strong>meaning only one goroutine was able to create a single instance.<\/li>There are a couple of outputs of \"Single Instance already created-1\"<\/strong> meaning that some of the goroutines found the value of singleInstance as nil in the first check and bypassed that.<\/li>There are couple of output of \"Single Instance already created-2\" <\/strong>meaning by the time they reached the single instance was already created and they could not bypass the first if check<\/li><\/ul>\n\n\n\nOther methods of creating a singleton object in Go<\/strong><\/p>\n\n\n\ninit() function<\/strong><\/li><\/ul>\n\n\n\nWe can create a single instance inside the init function. This is only applicable if the early initialization of the object is ok. The init function is only called once per file in a package, so we can be sure that only a single instance will be created. <\/p>\n\n\n\n
sync.Once<\/strong><\/li><\/ul>\n\n\n\nThe sync.Once will only perform the operation only once. See below code<\/p>\n\n\n\n
single.go<\/strong><\/p>\n\n\n\nvar once sync.Once\n\ntype single struct {\n}\n\nvar singleInstance *single\n\nfunc getInstance() *single {\n if singleInstance == nil {\n once.Do(\n func() {\n fmt.Println(\"Creting Single Instance Now\")\n singleInstance = &single{}\n })\n } else {\n fmt.Println(\"Single Instance already created-2\")\n }\n return singleInstance\n}<\/code><\/pre>\n\n\n\nOutput:<\/strong><\/p>\n\n\n\nCreting Single Instance Now\nSingle Instance already created-2\nSingle Instance already created-2<\/code><\/pre>\n\n\n\nThere is one output of \"Creating Single Instance Now\" <\/strong>meaning only one goroutine was able to create the single instance<\/li>There are couple of output of \"Single Instance already created-2\" <\/strong>meaning by the time they reached the single instance was already created and they could not bypass the first if check<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"Note: Interested in understanding how all other design patterns can be implemented in GO. Please see this full reference – All Design Patterns in Go (Golang) Introduction: Singleton Design Pattern is a…<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false},"categories":[1],"tags":[80,79],"class_list":["post-652","post","type-post","status-publish","format-standard","hentry","category-tech","tag-singleton","tag-singleton-design-pattern-in-golang"],"yoast_head":"\n
Singleton Design Pattern in Go (Golang) - Welcome To Golang By Example<\/title>\n \n \n \n \n \n \n \n \n \n \n \n \n \n\t \n\t \n\t \n