Wenn es um einfache Benutzerbarkeit geht, gibt es System.Generics.Collections.TThreadList<T>, die das Locking intern über TMonitor regelt.
Wie oft passieren denn Lese- und Schreibzugriffe? Wenn Schreibzugriffe im Vergleich deutlich seltener als Lesezugriffe sind (die ja nicht synchronisiert werden müssen), gibt es System.SyncObjs.TLightweightMREW, das für diesen Fall sehr performant ist.
Vorsicht! Lesezugriffe auf eine Liste müssen durchaus synchronisiert werden, wenn ein anderer Thread die Zahl oder Reihenfolge der Items ändern kann, besonders, wenn das Lesen in einer Schleife erfolgt.