Single-case mode for Go

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Singleton mode is a kind of common software design pattern. In its core structure, it contains only a special class called a singleton class. The singleton mode can ensure that there is only one instance of a class in the system, and the instance is easy to be accessed by the outside world, thus it is convenient to control the number of instances and save system resources. Singleton mode is the best solution if you want to have only one object for a class in the system.

1.Go implementation of a non-thread-safe Singleton mode (lazy is the idle single-case haha):

Package <textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="-moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4; font-size: 12px !important; line-height: 15px !important;">Singletontype Singleton struct {}var instance *singletonfunc getinstance () *singleton {If instance = nil {ins tance = &singleton{}//<---Not THREAD safe}return instance}</textarea>
12345678910111213 Package Singletontype Singleton struct {}var instance *Singletonfuncgetinstance() *Singleton {if instance == Nil {instance = &Singleton{}   //<---not THREAD SAFE}return instance}

The non-thread-safe singleton pattern is one of the most widely used. Many of the open source projects on GitHub use non-threaded security.

This type of lazy loading is obvious, but the fatal is that the multithreading does not work properly.

2.Go implementation of a single-case mode with a thread lock

<textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="-moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4; font-size: 12px !important; line-height: 15px !important;">var mu sync.mutexfunc getinstance () *singleton {mu. Lock ()//<---Unnecessary locking if instance already created defer MU. Unlock () If instance = = Nil {instance = &singleton{}} return instance}</textarea>
1234567891011 var muSync.Mutexfuncgetinstance() *Singleton {    mu.Lock()                    //<---Unnecessary locking if instance already created    defermu.Unlock()    if instance == Nil {        instance = &Singleton{}    }    return instance}

Here's the go.

<textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="-moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4; font-size: 12px !important; line-height: 15px !important;">Sync.mutex</textarea>
1 Sync . Mutex

Sync/mutex is one of the underlying basic objects of the go language, used to build synchronization logic between multiple goroutine, and is therefore used by a large number of high-level objects.
Its working model is similar to the Linux kernel Futex object, the implementation is very concise, performance is guaranteed.

The mutex object has only two numeric fields, divided into state (stored states) and SEMA (the amount of semaphores used to calculate the number of sleep goroutine).
The 0 value that is filled in during initialization sets the mutex to an unlocked state, while guaranteeing minimal time overhead.
This feature allows the mutex to be used as a sub-object of other objects.

3. Single-case mode with check lock

<textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="-moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4; font-size: 12px !important; line-height: 15px !important;">func getinstance () *singleton {if instance = = Nil {//<--not yet perfect. Since it's not fully atomic Mu. Lock () defer MU. Unlock () If instance = = Nil {instance = &singleton{}}} return instance}</textarea>
1234567891011 funcgetinstance() *Singleton {    if instance == Nil {     //<--not yet perfect. Since it's not fully atomic        mu.Lock()        defermu.Unlock()        if instance == Nil {            instance = &Singleton{}        }    }    return instance}

It's a good way, but it's not perfect. Because compiler optimizations do not check the instance store state. If you use the Sync/atomic package, you can automatically load and set the tag for us.

<textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="-moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4; font-size: 12px !important; line-height: 15px !important;">import "Sync" import "Sync/atomic" var initialized uint32...func getinstance () *singleton {if atomic. LoadUInt32 (&initialized) = = 1 {return instance} mu. Lock () defer MU. Unlock () if initialized = = 0 {instance = &singleton{} atomic. StoreUint32 (&initialized, 1)} return instance}</textarea>
12345678910111213141516171819202122 Import "Sync"Import "Sync/atomic"var initializedUInt32...funcgetinstance() *Singleton {    if Atomic.LoadUInt32(&initialized) == 1 {return instance}    mu.Lock()    defermu.Unlock()    if initialized == 0 {         instance = &Singleton{}         Atomic.StoreUint32(&initialized, 1)    }    return instance}

Personally think that a better use of a single case in Go is this

Package <textarea wrap="soft" class="crayon-plain print-no" data-settings="dblclick" readonly="" style="-moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4; font-size: 12px !important; line-height: 15px !important;">singletonimport ("Sync") type singleton struct {}var instance *singletonvar once sync. Oncefunc getinstance () *singleton {once. Do (func () {instance = &singleton{}}) return instance}</textarea>
123456789101112131415161718 Package SingletonImport (    "Sync")type Singleton struct {}var instance *Singletonvar onceSync.Once funcgetinstance() *Singleton {    once. Do(func() {        instance = &Singleton{}    })    return instance}

By using Sync. The Once package enables thread-safe singleton mode.

If there is something wrong with the writing, the place welcomes the point.

single-case mode for Go

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.