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)”两次。因此,每次线程进入时,它都很可能锁定一个新对象。感谢您的解释。