Chce używać tablicy generycznej przykładowo Dictionary<T,T> lub List<T> w kilku wątkach i tutaj moje pytanie jak najlepiej zabezpieczyć je przed wszelkimi błędami związanymi z wielowątkowości, tutaj mam parę moich propozycji lecz nie znam się na tym na tyle żeby wiedzieć czy one są dobre:

tablice będzie nosić nazwę "List".

1 (to podałem bo nie wiem czy po prostu sam lock wystarczy w funkcji pobierającej aby do końca używania listy była ona zablokowana):

class BlaBla
{
    private static BlaBla Instance;

    private readonly object ListLock = new object();
    private List<T> List;

    public L2World()
    {
        this.List = new List<T>();
    }

    public static BlaBla GetInstance()
    {
        if (Instance == null)
            Instance = new BlaBla();

        return Instance;
    }

    public List<T> GetList()
    {
        lock(ListLock)
            return List;
    }
}

2 (zwykły lock):

// Jakiś wątek:
lock(BlaBla.ListLock)
{
    List<T> bbb = BlaBla.GetInstance().GetList();
    foreach(T ccc in bbb)
    {
        coś tam coś tam...
    }
}

// jakaś tam sobie klasa
class BlaBla
{
    private static BlaBla Instance;

    public static readonly object ListLock = new object();
    private List<T> List;

    public L2World()
    {
        this.List = new List<T>();
    }

    public static BlaBla GetInstance()
    {
        if (Instance == null)
            Instance = new BlaBla();

        return Instance;
    }

    public List<T> GetList()
    {
        return List;
    }
}

3 (System.Threading.ReaderWriterLock lock):

// Jakiś wątek:
BlaBla.GetInstance().ListLock.AcquireReaderLock(99999999999);
try
{
    List<T> bbb = BlaBla.GetInstance().GetList();
    foreach(T ccc in bbb)
    {
        coś tam coś tam...
    }
}
finally
{
    BlaBla.GetInstance().ListLock.ReleaseReaderLock();
}

// jakaś tam sobie klasa
class BlaBla
{
    private static BlaBla Instance;

    public System.Threading.ReaderWriterLock ListLock = new System.Threading.ReaderWriterLock();
    private List<T> List;

    public L2World()
    {
        this.List = new List<T>();
    }

    public static BlaBla GetInstance()
    {
        if (Instance == null)
            Instance = new BlaBla();

        return Instance;
    }

    public List<T> GetList()
    {
        return List;
    }
}

Będę wdzięczny za pomoc i inne, może lepsze propozycje. :)