多个线程,读写List<int>中的不同元素,相互有影响吗?

解决方案 »

  1.   

    这个要看怎么说了,如果线程读的时候没什么关系,list不变化,那么就没关系的
      

  2.   

    每个线程读写都是各自的List <int>元素,不重叠。
      

  3.   

    每个线程读取和修改各自的List不会有影响。只有在多个线程读取和修改同一个共享资源(如List)时就要才采取同步策略了。
      

  4.   

    写时肯定有影响,一般需要lock()或Monitor.Enter()/Exit()等同步手段。
      

  5.   

    在程序中开多个线程,编程的时候不知道几个,每个线程分给相同类型的不同资源,如某种结构体,由于是动态生成,编程时也不知道多少,但是每个线程对应一个,就把它们放在一个List〈〉中。这样就能管理他们了,每个线程处理各自的资源,只不过它们都放在一起在List〈〉中。
      

  6.   

    会影响的,必须对list的访问加锁
      

  7.   

    此类问题参考msdn
    http://msdn.microsoft.com/zh-cn/library/6sh2ey19(VS.80).aspx此类型的公共静态(在 Visual Basic 中为 Shared)成员是线程安全的。但不能保证任何实例成员是线程安全的。只要不修改该集合,List 就可以同时支持多个阅读器。通过集合枚举在本质上不是一个线程安全的过程。在枚举与一个或多个写访问竞争的罕见情况下,确保线程安全的唯一方法是在整个枚举期间锁定集合。若要允许多个线程访问集合以进行读写操作,则必须实现自己的同步。
    写访问时加lock控制块就可以了。
      

  8.   

    在开线程的时候就把数据传递给线程,这样数据就不会互相冲突了。但我认为既然是多线程,其目的就是为了并行的做麽一件事,以提高完成这件事的速度,那么极有可能会涉及到共享的数据,所以加锁无法避免。一个锁也耗不了多少资源的,你对一个list加锁,基本不会影响到你的操作,就在ADD Remove,GEt,Clear上加上同一个锁就可以了。
      

  9.   

    加lock会影响速度。就违背了每个线程有自己的资源的初衷。
    大家能有什么办法管理在程序中的动态资源,又不把它们组合成List之类的东西?
    谢谢!
      

  10.   

    还有一个办法,就是把你的每个线程访问的变量定义为Static,然后用ThreadStatic标注,就是每线程的了[ThreadStatic]
    private static List<T> _data ;public static List Data
    {
    get
    {
     if(_data == null)
    {
    _data = new List<T>();
    }
    return _data;
    }
    }这样变量就跟线程绑定,线程之间不会互相影响
    但我觉得最后你还是得把线程运行结果放到共享数据里去~~~
      

  11.   

    你不需要共享的数据,干嘛去加lock??就如你刚刚说的list,就只有在线程起来的时候去访问一下,能影响多少速度呢?当然你的线程要声明一个变量指向你从list里Get的数据就可以了。多线程编程,对于共享数据的数据一致性问题是不可避免的,解决这个办法的途径通用的就是加lock,这个是效率最高的了,只是在使用的时候尽量减少访问lock了的资源。
    这个世界上不会有不要钱的午餐,你要多线程,又要访问共享数据,又要不发生有次序,总的有地方要损失些东西。
      

  12.   

    读取和修改同一个共List时就要同步,否则会出错
      

  13.   


    有指针又怎么样?多线程处理共享数据用指针就能避免数据不发生混乱,A线程用指针指向C,B线程也用指针指向C,有个操作是C = C + 1,这个时候A和B同时执行这个操作,你认为C会是多少,是C + 2
    还是C + 1?看来楼主对多线程的认识还是比较肤浅的。
      

  14.   

    楼上的,LocalDataStoreSlot这个可以吗?
      

  15.   

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

  16.   

    楼上的老兄:具体得太长,写概要
    K = ThreadK();//计算要开的线程数,和具体问题规模有关。
    for(i=0;i〈k;i++)
    {
       Data MyData = new Data();//每一线程一个,不共享,因为问题规模太大,频繁写,用lock会影响效率。
       Thread MyThread = new System.Threading.Thread(new System.Threading.ThreadStart(MyData.Deal));
    };现在是MyData在运算前不知道个数,MyData在线程结束后还要进一步处理,问题是如何管理未知个数的MyData
      

  17.   

    具体得太长,写概要
    K = ThreadK();//计算要开的线程数,和具体问题规模有关。
    for(i=0;i〈k;i++)
    {
      Data MyData = new Data();//每一线程一个,不共享,因为问题规模太大,频繁写,用lock会影响效率。
      Thread MyThread = new System.Threading.Thread(new System.Threading.ThreadStart(MyData.Deal));
      MyThread.Start();
    };现在是MyData在运算前不知道个数,MyData在线程结束后还要进一步处理,问题是如何管理未知个数的MyData
      

  18.   

    如果每个线程对应一个的话还是用Dictionary<int,Data >比较好,有唯一性而且是线程安全的
      

  19.   

    tmxk2002:
    从里面进一步提取信息,以供输出。
      

  20.   

    K = ThreadK();//计算要开的线程数,和具体问题规模有关。 
    Data[] myDatas = new Data[K];
    AutoResetEvent[] resetEvents = new AutoResetEvent[K];
    for(i=0;i〈k;i++) 

      resetEvents[i] = new AutoResetEvent(false);
      Data MyData = new Data(resetEvents[i]);//每一线程一个,不共享,因为问题规模太大,频繁写,用lock会影响效率。 
      Thread MyThread = new System.Threading.Thread(new System.Threading.ThreadStart(MyData.Deal)); 
      MyThread.Start(); 
    }; AutoResetEvent.WaitAll(resetEvents);//等待所有线程都处理完....//后面的处理
    ------------------------------------class Data
    {
    AutoResetEvent _notifyToInvoker = null;public Data(AutoResetEvent notifyToInvoker )//将信号量传入到你封装的Data类中,以便Deal做完后通知主线程.
    {
    _notifyToInvoker = notifyToInvoker ;
    }
     void Deal()
    {
    ...
    _notifyToInvoker.Set();
    }
    }
      

  21.   

    K = ThreadK();//计算要开的线程数,和具体问题规模有关。 
    Data[] myDatas = new Data[K]; 
    AutoResetEvent[] resetEvents = new AutoResetEvent[K]; 
    for(i=0;i〈k;i++) 

      resetEvents[i] = new AutoResetEvent(false); 
      MyDatas[i] = new Data(resetEvents[i]);//每一线程一个,不共享,因为问题规模太大,频繁写,用lock会影响效率。 
      Thread MyThread = new System.Threading.Thread(new System.Threading.ThreadStart(MyDatas[i].Deal)); 
      MyThread.Start(); 
    }; AutoResetEvent.WaitAll(resetEvents);//等待所有线程都处理完. ...//后面的处理 
    ------------------------------------ class Data 

    AutoResetEvent _notifyToInvoker = null; public Data(AutoResetEvent notifyToInvoker )//将信号量传入到你封装的Data类中,以便Deal做完后通知主线程. 

    _notifyToInvoker = notifyToInvoker ; 

    void Deal() 

    ... 
    _notifyToInvoker.Set(); 

    }