静态Arraylist是否线程安全?包括在集合枚举时是否也安全的?比如在枚举时还有其他线程在向集合中写入数据。
请教,谢谢。

解决方案 »

  1.   

    我只能告诉你看msdn的描述,以前看msdn老是有一段说什么县城安全的,但从来没用到。
      

  2.   

    最好是谁具体用过的,有事实依据的,msdn描述含糊不清,不太明白。
      

  3.   

    此类型的公共静态(在 Visual Basic 中为 Shared)成员是线程安全的。但不能保证任何实例成员是线程安全的。只要集合未修改,ArrayList 就可以同时支持多个阅读器。若要保证 ArrayList 的线程安全,则必须通过由 Synchronized 方法返回的包装来执行所有操作。从头到尾对一个集合进行枚举本质上并不是一个线程安全的过程。即使一个集合已进行同步,其他线程仍可以修改该集合,这将导致枚举数引发异常。若要在枚举过程中保证线程安全,可以在整个枚举过程中锁定集合,或者捕捉由于其他线程进行的更改而引发的异常。
    -------------------
    官方文档说的很清楚...不能保证任何实例成员是线程安全的...解决方法说的也很清楚...在整个枚举过程中锁定集合,或者捕捉由于其他线程进行的更改而引发的异常...
      

  4.   

    从头到尾对一个集合进行枚举本质上并不是一个线程安全的过程就是foreach ArrayList时,其它线程改了它,不能得到即时反映除非你采用lock,或其他线程进行的更改而引发的异常=============================
    即使一个集合已进行同步,其他线程仍可以修改该集合,这将导致枚举数引发异常 
    .net采用的同步方法是,如果别的线程修改了,foreach将会导致异常
      

  5.   

    using System;
    using System.Collections;
    using System.Threading;namespace MonitorCS2
    {
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class MonitorSample
    {
    //Define the queue to safe thread access.
    private Queue m_inputQueue; public MonitorSample()
    {
    m_inputQueue = new Queue(); 
    } //Add an element to the queue and obtain the monitor lock for the queue object.
    public void AddElement(object qValue)
    {
    //Lock the queue.
    Monitor.Enter(m_inputQueue);
    //Add element
    m_inputQueue.Enqueue(qValue);
    //Unlock the queue.
    Monitor.Exit(m_inputQueue);
    } //Try to add an element to the queue.
    //Add the element to the queue only if the queue object is unlocked.
    public bool AddElementWithoutWait(object qValue)
    {
    //Determine whether the queue is locked 
    if(!Monitor.TryEnter(m_inputQueue))
    return false;
    m_inputQueue.Enqueue(qValue); Monitor.Exit(m_inputQueue);
    return true;
    } //Try to add an element to the queue. 
    //Add the element to the queue only if during the specified time the queue object will be unlocked.
    public bool WaitToAddElement(object qValue, int waitTime)
    {
    //Wait while the queue is locked.
    if(!Monitor.TryEnter(m_inputQueue,waitTime))
    return false;
    m_inputQueue.Enqueue(qValue);
    Monitor.Exit(m_inputQueue); return true;
    }

    //Delete all elements that equal the given object and obtain the monitor lock for the queue object.
    public void DeleteElement(object qValue)
    {
    //Lock the queue.
    Monitor.Enter(m_inputQueue);
    int counter = m_inputQueue.Count;
    while(counter > 0)
    {
    //Check each element.
    object elm = m_inputQueue.Dequeue();
    if(!elm.Equals(qValue))
    {
    m_inputQueue.Enqueue(elm);
    }
    --counter;
    }
    //Unlock the queue.
    Monitor.Exit(m_inputQueue);
    }

    //Print all queue elements.
    public void PrintAllElements()
    {
    //Lock the queue.
    Monitor.Enter(m_inputQueue);
    IEnumerator elmEnum = m_inputQueue.GetEnumerator();
    while(elmEnum.MoveNext())
    {
    //Print the next element.
    Console.WriteLine(elmEnum.Current.ToString());
    }
    //Unlock the queue.
    Monitor.Exit(m_inputQueue);
    } static void Main(string[] args)
    {
    MonitorSample sample = new MonitorSample();

    for(int i = 0; i < 30; i++)
    sample.AddElement(i);
    sample.PrintAllElements();
    sample.DeleteElement(0);
    sample.DeleteElement(10);
    sample.DeleteElement(20);
    sample.PrintAllElements(); }
    }
    }