【问题标题】:Arraylist Synchronization issueArraylist 同步问题
【发布时间】:2012-09-21 12:16:08
【问题描述】:

我有一个每秒不断更新的数组列表。我必须在另外两个线程中使用相同的数组列表并制作它的本地副本。我已经完成了所有这些,但是我得到了 index out of bound 的奇怪异常,到目前为止我发现我必须确保数组列表的一些同步机制可以跨多个线程使用。

这就是我让它同步的方式:

for (int i = 0; i < Globls.iterationCount; i++)
            {
                if (bw_Obj.CancellationPending)
                {
                    eve.Cancel = true;
                    break;
                }

                byte[] rawData4 = DMM4.IO.Read(4 * numReadings);
                TempDisplayData_DMM4.Add(rawData4);
                Globls.Display_DataDMM4 = ArrayList.Synchronized(TempDisplayData_DMM4);
                Globls.Write_DataDMM4 = ArrayList.Synchronized(TempDisplayData_DMM4);

            }

在其他线程中,我执行以下操作来制作本地副本:

ArrayList Local_Write_DMM4 = new ArrayList();
Local_Write_DMM4 = new ArrayList(Globls.Write_DataDMM4); 

我是否以正确的方式同步数组列表?,在复制数组列表时我是否也需要锁定:

 lock (Globls.Display_DataDMM4.SyncRoot){Local_Temp_Display1 = new ArrayList(Globls.Display_DataDMM4);}

或者对于单一操作它安全吗?我实际上并没有运行这段代码,我需要在周末运行它,我不想看到另一个异常:(。请帮助我!

【问题讨论】:

  • 你能解释一下你的目标是什么吗?避免异常是次要的。您是否担心包含不同内容列表的两个线程?还是担心一个线程可能会在另一个线程正在阅读时更改列表项?
  • 您的问题的解决方案:link
  • @chris 数组列表永远不会有不同的内容。我试图在复制 Local_Write_DMM4 = new ArrayList(Globls.Write_DataDMM4); 时避免异常我使用了上述方法,我问了两个我主要关心的问题
  • @Trickery 我已经看到了那个链接,我没有得到的是数组的分配也需要一个锁?

标签: c# multithreading arraylist synchronization locking


【解决方案1】:

正如@Trickery 所说,分配需要被锁定,因为源数组Globls.Write_DataDMM4 可以在枚举期间被另一个线程修改。 因此,必须在填充原始数组时同时锁定在制作副本时锁定

for (int i = 0; i < Globls.iterationCount; i++)
{
    if (bw_Obj.CancellationPending)
    {
        eve.Cancel = true;
        break;
    }

    byte[] rawData4 = DMM4.IO.Read(4 * numReadings);
    TempDisplayData_DMM4.Add(rawData4);

    lock (Globls.Display_DataDMM4.SyncRoot)
    {
    Globls.Write_DataDMM4 = ArrayList.Synchronized(TempDisplayData_DMM4);
    }

}

lock (Globls.Display_DataDMM4.SyncRoot)
{
     Local_Temp_Display1 = new ArrayList(Globls.Display_DataDMM4);
}

【讨论】:

  • 如果我不做作业怎么办:Globls.Write_DataDMM4 = ArrayList.Synchronized(TempDisplayData_DMM4);相反,我初始化公共静态 ArrayList Write_DataDMM4 = ArrayList.Synchronized(new ArrayList());我只是添加到列表 Globls.Display_DataDMM4.Add(rawData); ,我已经同步了arraylist,从我添加数据开始,是否也需要锁定它?
  • public static 声明可能是个好主意,但您仍需要在.Add() 阶段锁定。见this article
  • 好吧,文章提到添加/删除不会损坏列表,我在没有锁定添加的情况下运行了 70 小时测试,它没有造成任何问题,谢谢!
【解决方案2】:

是的,对你的 ArrayList 的所有操作都需要使用 Lock。

编辑:抱歉,由于某种原因,该网站不允许我对您的问题添加评论。

【讨论】:

    猜你喜欢
    • 2015-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 2011-07-15
    • 2015-05-03
    • 2012-11-01
    • 2011-09-10
    相关资源
    最近更新 更多