c # seguridad de subprocesos de colecciones

URL original: http://www.cnblogs.com/Clingingboy/archive/2010/12/06/1897534.html

Es decir, las colecciones ubicadas en el espacio de nombres System.Collections, como Hashtable, ArrayList, Stack, Queue, etc. Todas proporcionan una implementación de sincronización de subprocesos

Problema de sincronización del hilo de la colección

public class Demo8
{
    ArrayList list = new ArrayList(1000000);
    public Demo8()
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(Task1));
        ThreadPool.QueueUserWorkItem(new WaitCallback(Task2));
    }

    public void Task1(object obj)
    {
        for (int i = 0; i < 500000; i++)
        {
            list.Add(i);
        }

        Console.WriteLine(DateTime.Now);
        Console.WriteLine("Task1 count {0}", list.Count);
    }

    public void Task2(object obj)
    {
        for (int i = 0; i < 500000; i++)
        {
            list.Add(i);
        }

        Console.WriteLine("Task2 count {0}", list.Count);
    }
}
imagen

Diferente del resultado esperado

Ajustado a una colección de sincronización de subprocesos

Cada tipo de datos contiene un método sincronizado estático, como

ArrayList list = ArrayList.Synchronized(new ArrayList(1000000));

Resultado ajustado

imagen 
Los siguientes son puntos a tener en cuenta:

  1. IsSynchronized determina si la colección está sincronizada con subprocesos
  2. La sincronización interna se realiza bloqueando el atributo SyncRoot (es decir, Monitor.Enter)

Controla la cerradura tú mismo

public class Demo8
{
    ArrayList list = new ArrayList(1000000);
    public Demo8()
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(Task1));
        ThreadPool.QueueUserWorkItem(new WaitCallback(Task2));
    }

    public void Task1(object obj)
    {
        lock (list.SyncRoot)
        {
            for (int i = 0; i < 500000; i++)
            {
                list.Add(i);
            }
        } 
       
        Console.WriteLine(DateTime.Now);
        Console.WriteLine("Task1 count {0}", list.Count);
    }

    public void Task2(object obj)
    {
        lock (list.SyncRoot)
        {
            for (int i = 0; i < 500000; i++)
            {
                list.Add(i);
            }
        }
        Console.WriteLine("Task2 count {0}", list.Count);
    }
}

imagen

Este resultado es obviamente atractivo. La implementación interna está bloqueada en el método Add. El efecto, naturalmente, no es muy bueno.

Otras clases de colección son operaciones similares



Supongo que te gusta

Origin blog.csdn.net/youarenotme/article/details/77882286
Recomendado
Clasificación