在多个线程中设置对象的属性

本文关键字:对象 属性 设置 线程 | 更新日期: 2023-09-27 18:05:30

我会尽力说明情况的。

public class A
{
    Int64 Id { get; set; }
    Decimal Foo { get; set; }
}
public class B
{
    Int64 Id { get; set; }
    Decimal Bar { get; set; }
}
public class C
{
    Int64 Id { get; set; }
    Decimal? Foo { get; set; }
    Decimal? Bar { get; set; }
}
public class test
{
    ConcurrentDictionary<Int64, C> dictionary { get; set; }
    List<A> listA { get; set; } 
    List<B> listB { get; set; }
}

listA和listB各包含500万个对象。

我所做的是,在不同的线程上循环listA和listB。我检查字典中是否包含id,然后获取值并设置匹配属性。

所以我的问题是,这是线程安全吗?如果不是,什么是使它线程安全的最好方法

还有一点:

  • 列表a和列表b中没有重复项。所以我只设置任何对象C的属性一次。

一个使用虚拟数据的例子:

List<A> listA = new List<A> 
{ 
    new A { Id = 1, Foo = 5 },
    new A { Id = 2, Foo = 10 },
    new A { Id = 3, Foo = 100 }
};
List<B> listB = new List<B> 
{ 
    new A { Id = 1, Bar = 3 },
    new A { Id = 2, Bar = 2 },
    new A { Id = 3, Bar = 1 }
};
ConcurrentDictionary<Int64, C> dictionary = new ConcurrentDictionary<Int64, C>
{
    Keys = {1, 2, 3},
    Values = { new C { Id = 1 }, new C { Id = 2 }, new C { Id = 3 } }
};

之后,字典将有这些键/值对:

Key = 1 , value = object of class C with properties : Id = 1, Foo = 5, Bar = 3,
Key = 1 , value = object of class C with properties : Id = 1, Foo = 10, Bar = 2,
Key = 1 , value = object of class C with properties : Id = 1, Foo = 100, Bar = 1    

在多个线程中设置对象的属性

如果你在循环中所做的是访问并发字典中已经存在的对象C,并分别设置属性Foo和Bar,那么是的,这应该是线程安全的。

如果你正在从ConcurrentDictionary中插入或删除项,只要你正确地使用ConcurrentDictionary,那也应该是线程安全的。

ConcurrentDictionary是线程安全的。

https://msdn.microsoft.com/en-us/library/dd287191 (v = vs.110) . aspx表示可由多个线程并发访问的键/值对的线程安全集合。

因此,您应该能够从任意数量的线程访问它。但是有一个问题

假设你的字典是空的,两个线程检查目标ID的对象是否存在,如果不存在则继续添加新对象,这可能发生两个线程都试图添加相同的新项目。因此,您的字典必须已经包含了这些对象,否则您将不得不使用锁。