新锁内

时间:2011-03-16 16:41:21

标签: c# multithreading locking

我注意到来自外国程序员的以下代码:

private Client[] clients = new Client[0];

public CreateClients(int count)
{
    lock (clients)
    {
        clients = new Client[count];

        for(int i=0; i<count; i++)
        {
           Client[i] = new Client();//Stripped
        }
     }
 }

这不是完全正确的代码,但我想知道这究竟是做什么的。每次调用此方法时,这会锁定一个新对象吗?

5 个答案:

答案 0 :(得分:5)

要回答你的问题“我想知道这将做什么”,请考虑如果两个线程试图这样做会发生什么。

Thread 1: locks on the clients reference, which is `new Client[0]`
   Thread 1 has entered the critical  block
Thread 1: makes a array and assigns it to the clients reference
Thread 2: locks on the clients reference, which is the array just made in thread 1
   Thread 2 has entered the critical block

你知道在关键区块中同时有两个线程。那很糟糕。

答案 1 :(得分:1)

此代码错误 - 每次调用它时都会锁定一个新实例。

看起来应该是这样的:

private static readonly object clientsLock = new object();
private static string[] Clients = null;

public CreateClients(int count)
{
    if(clients == null)
    {
        lock (clientsLock)
        {
            if(clients == null)
            {
                clients = new string[count];

                for(int i=0; i<count; i++)
                {
                     client[i] = new Client();//Stripped
                }
            }
        }
     }
 }

每次调用方法时锁定都没有意义 - 这就是周围if子句的原因。

答案 2 :(得分:1)

使用:
private object = new Object();

lock(object){

//your code

}

答案 3 :(得分:1)

lock确实无能为力。它锁定一个立即更改的对象实例,以便进入此方法的其他线程将lock放在另一个对象上。结果是在lock中间执行的2个线程可能不是预期的。

这里更好的方法是使用不同的,不变的对象来锁定

private readonly object clientsLock = new object();
private Client[] clients = new Client[0];  

public CreateClients(int count) {     
  lock (clientsLock) {         
    clients = new string[count]; 
    ...
  }
}

答案 4 :(得分:0)

我认为你怀疑这段代码是对的!

此代码每次都会锁定前一个实例 - 这可能是所需的效果,但我对此表示怀疑。它不会阻止多个线程创建多个阵列。