这个单例实现线程是否安全 - 检查代码

rti*_*dru 3 c# singleton design-patterns thread-safety

我有一个数据库连接的类实现.现在,这不是标准的SQL数据库.

我需要知道以下是否是一个好的实现,如果不是 - 为什么.

我需要一个带参数的单例类,这就是我设计的方法.

class Connection 
{
    private string param1;
    private string param2;
    private static readonly IList<Connection> connections = new List<Connection>();
    private Connection()
    {
        //Prevent instantiation
    }

    private Connection(string param1, string param2)
    {
        this.param1 = param1;
        this.param2 = param2;
    }

    public static Connection getInstance(string param1, string param2)
    { 
        foreach(Connection c in connections)
        {
            if(c.param1 = param1 && c.param2 == param2)
                return c;
        }
        Connection new_conn = new Connection(param1, param2);
        connections.Add(new_conn);
        return new_conn;
    }
}
Run Code Online (Sandbox Code Playgroud)

它将使用如下:

Connection c = Connection.getInstance(abc, xyz);
Connection d = Conn
Run Code Online (Sandbox Code Playgroud)

*更新 - 现在好吗?*

class Connection 
{
    private string param1;
    private string param2;
    private static readonly ConcurrentDictionary<Tuple<string, string, string>, Connection> connections
        = new ConcurrentDictionary<Tuple<string, string>, Connection>();
    private Connection()
    {
        //Prevent instantiation
    }

    private Connection(string param1, string param2)
    {
        this.param1 = param1;
        this.param2 = param2;
    }

    public static Connection getInstance(string param1, string param2)
    { 
        Connection conn = activeConnections.GetOrAdd(new Tuple<string, string> 
            param1,param2), new Connection (param1, param2));
        return conn;
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 7

不,它不是线程安全的 - 您在List<T>没有任何同步的情况下进行修改,并且List<T>不是线程安全的.

此外,如果两个调用同时进入,则最终可能会有两个具有相同参数的连接,两个调用都会查看所有现有连接,然后创建一个新连接.

我建议你使用ConcurrentDictionary两个参数的元组键.除此之外,这也会更有效率.

您需要调用GetOrAdd以获取现有连接或创建并添加新连接.