2013-01-20 47 views
3

因此,它在C#中,基本上我会有一个数组中的位置为每个线程存储一些数据。我需要锁定吗?例如:多个线程写入阵列

int[] threads = new int[12]; 

每个线程将访问阵列例如在一个特定的位置时,线程1将更新线程的值[0],线程2个线程[1],等等

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

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

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

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

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

+2

请注意,由于[错误分享](https://en.wikipedia.org/wiki/False_sharing),这可能是无效的。除非你非常清楚**你正在做什么,否则将多个线程写入通用对象(并发集合除外)永远不是一个好主意。你应该重构你的程序流程,这样就没有必要。 –

+0

我非常同意@KonradRudolph在这里 - [见我给另一个SO的答案](http://stackoverflow.com/questions/12390468/multithreading-slower-than-singlethreading/12390662#12390662)OP描述的情况其中多线程应用程序比单线程版本慢(包括一个非常好的链接到一个优秀的MSDN文章)。我这样做并不是为了获得新答案 - 但是因为这是一个很少被人理解的现象,人们越多越好:) –

+2

这些家伙是对的。这闻起来很可怕。记住,你应该像对待员工那样对待线索:他们很贵,所以不要雇用他们,除非你有很多工作要做。那些线程将大部分时间都闲置,等待数据库。如果你期待12封信,你会雇用12位秘书在邮箱旁等待吗?除非他们使你的处理器达到最大化,否则不要创建线程,也不要制造比处理器更多的线程。 –

回答

2

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

我相信如果你产生了一堆线程,每一个线程都填充它自己的数组部分,那么等待所有这些线程完成使用Thread.Join,这将为你做到足够的障碍注意安全。

MSDN documentation on Arrays说:

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

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

枚举整个集合是 本质上不是线程安全的 过程。即使集合是 同步,其他线程仍可以 修改集合,这会导致枚举器引发 引发异常。 要在枚举中保证线程安全,您可以在整个 枚举期间锁定 集合,或者捕获由其他 线程所做更改产生的异常 。

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

4

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

+1

这应该也是我的回答,虽然它仍然是一个灾难的食谱:) – slugster

+1

请详细说明食谱灾难.. – sridawg

+0

@sridawg - 这是一个灾难的食谱,因为在某个地方,你可能访问多个结构线程...在这种情况下,事情不再是线程安全的。 –