登录
首页 >  Golang >  Go问答

互斥锁如何与单例一起工作?

来源:stackoverflow

时间:2024-04-17 22:33:35 188浏览 收藏

本篇文章主要是结合我之前面试的各种经历和实战开发中遇到的问题解决经验整理的,希望这篇《互斥锁如何与单例一起工作?》对你有很大帮助!欢迎收藏,分享给更多的需要的朋友学习~

问题内容

我用数据库连接器实现了单例。 它工作正常,但我无法理解 lock (mutex.lock()) 正在做什么。

我试图理解这一点,但也许这里有人可以告诉我更多有关此的信息。

我是这样理解的-> 使用 lock() 后,lock 和 unlock 之间的整个代码可以仅由一个 goroutine 运行。 如果这是事实,那不是一个瓶颈吗?这不是让我的应用程序变慢了吗?每个gorutine必须等待另一端执行这段代码。

package singleton

import (
    "database/sql"
    "fmt"
    "sync"
)

var connector *sql.db
var mutex = &sync.mutex{}

func openconnection() *sql.db {
    if connector == nil {
        mutex.lock()
        defer mutex.unlock()
        if connector == nil {
            fmt.println("creating single instance now")
            var err error
            connector, err = sql.open("mysql", "db_user:.db_password@/books")

            if err != nil {
                panic(err)
            }
        }
    }

    return connector
}
package server

import (
    "connection/singleton"
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
    "strings"
)

var connector *sql.DB

func SelectQuery(query string) (*sql.Rows, error) {
    connector = singelton.OpenConnection()
    query = strings.ToLower(query)
    if !strings.Contains(query, "select") {
        panic("Can't use select query to run different query")
    }

    results, err := connector.Query(query)

    if err != nil {
        panic(err.Error()) // proper error handling instead of panic in your app
    }

    return results, err
}

解决方案


我们在这里使用互斥锁的原因是只初始化一次数据库连接。这只会在开始时发生。一旦获得连接,OpenConnection 将始终返回连接,而不进入互斥体块。 所以不会有任何性能问题。

您还可以使用 sync.Once 方法实现相同的目的,而无需使用互斥体和双重检查。

好了,本文到此结束,带大家了解了《互斥锁如何与单例一起工作?》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多Golang知识!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>