5

所以它在 C# 中,基本上我将在一个数组中为每个线程存储一些数据。我需要锁定这个吗?例如:

int[] threads = new int[12];

每个线程将访问数组中的特定位置,例如,线程 1 将更新线程 [0]、线程 2 线程 [1] 等中的值。

想法是让控制台打印存储在数组中的值。

好吧,评论这么多。我想我会澄清我在做什么,希望我能学到更多。所以基本上它的要点是:

主线程启动12个独立线程,每个线程调用主线程中的一个函数从数据库中获取一堆记录。对该方法的访问被锁定,但它返回大约 100 条记录供线程自行处理。

当线程处理记录时,它会发出几个 Web 请求并插入到数据库中。一旦线程完成了它的一批记录的处理,它就会再次从主线程调用一个函数,并且该函数会启动一个新线程来代替最后一个正在完成的线程。

由于线程正在处理它们,我想在控制台中输出它们的进度。最初我锁定了每个控制台输出,因为如果同时调用相同的函数,每个输出的光标位置就会到处乱窜。所以我想我会有一个数组来存储每个值的计数,然后有一个函数把它全部打印出来。尽管我开始怀疑这是否真的与我目前所做的有什么不同。

4

2 回答 2

4

如果每个线程都在自己的索引处访问一个值,那么您应该没问题,因为您不必担心同时来自多个线程的访问。

于 2013-01-20T01:21:12.033 回答
2

我相信如果每个线程只在数组的一个单独部分上工作,一切都会好起来的。如果您要共享数据(即在线程之间进行通信),那么您将需要某种内存屏障来避免内存模型问题。

我相信,如果您生成一堆线程,每个线程都填充自己的数组部分,然后等待所有这些线程完成使用Thread.Join,那么就屏障而言,这将足以保证您的安全。

关于数组的 MSDN 文档说:

此类型的公共静态(在 Visual Basic 中为 Shared)成员是线程安全的。不保证任何实例成员都是线程安全的。

此实现不为 Array 提供同步(线程安全)包装器;但是,基于 Array 的 .NET Framework 类使用 SyncRoot 属性提供它们自己的同步版本的集合。

通过集合进行枚举本质上不是线程安全的过程。即使一个集合被同步,其他线程仍然可以修改该集合,这会导致枚举器抛出异常。为了保证枚举过程中的线程安全,您可以在整个枚举过程中锁定集合,也可以捕获其他线程更改导致的异常。

所以不,它们不是线程安全的。通常,当并发访问可能在内部失败时,集合被称为“非线程安全”,但由于每个线程将访问不同的位置,因此这里没有并发访问。

于 2013-01-20T01:24:37.103 回答