Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 新的锁里面_C#_Multithreading_Locking - Fatal编程技术网

C# 新的锁里面

C# 新的锁里面,c#,multithreading,locking,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();//Str

我从我们的外国程序员那里注意到以下代码:

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
        }
     }
 }
private Client[]clients=新客户端[0];
公共CreateClients(整数计数)
{
锁定(客户端)
{
客户=新客户[计数];

对于(inti=0;i这段代码是错误的-它将在每次调用时锁定一个新实例

应该是这样的:

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
                }
            }
        }
     }
 }
private static readonly object clientsLock=new object();
私有静态字符串[]Clients=null;
公共CreateClients(整数计数)
{
如果(客户端==null)
{
锁(clientsLock)
{
如果(客户端==null)
{
clients=新字符串[计数];
对于(int i=0;i使用:
private object=new object();

lock(object){

//your code

}

我认为你怀疑这个密码是对的


此代码每次都会锁定上一个实例-这可能是期望的效果,但我对此表示怀疑。它不会阻止多个线程创建多个数组。

锁定
实际上没有任何作用。它锁定一个对象的实例,该对象立即更改,使进入此方法的其他线程将
锁定一个不同的对象。结果是在<代码>锁中间执行的2个线程,这可能不是预期的。

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

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

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

回答你的问题“我想知道这到底会做什么”考虑如果两个线程试图做到这一点会发生什么。

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

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

锁定数组是一种不好的做法。最好定义用于同步的附加对象写入的代码是错误的,对吗?锁内不应该是clients=new Client[count],然后是clients[i]=new Client();?你说得对,编辑了它。它根本不是线程安全的。多个线程可能正在创建和使用不同的数组,一些Clinet()会丢失。@Henk OP知道这不好-问题是“发生了什么”也就是说,了解它有什么不好的行为。鉴于它是一个实例方法,我认为没有理由使用静态锁对象。这将永远不会进入,因为如果客户端!=null
它将始终为null,因为删除它的null的唯一方法是在
!=null
blo中是的,它可能应该是“if(clients==null)”两次。因此,每次线程进入时,它都很可能锁定一个新对象。感谢您的解释。