Est-il possible d'utiliser une chaîne comme un verrouillage de l'objet?

J'ai besoin de faire une section critique dans un domaine sur la base d'un ensemble fini de chaînes de caractères. Je veux la serrure pour être partagé pour la même instance de chaîne, (un peu comme Chaîne de caractères.Stagiaire approche).

Je suis d'examiner la mise en œuvre suivants:

public class Foo
{
    private readonly string _s;
    private static readonly HashSet<string> _locks = new HashSet<string>();

    public Foo(string s)
    {
        _s = s;
        _locks.Add(s);
    }

    public void LockMethod()
    {
        lock(_locks.Single(l => l == _s))
        {
            ...
        }
    }
}

Sont là des problèmes avec cette approche? Est-il OK pour verrou sur un objet de type string de cette façon, et il n'existe aucun fil des questions de sécurité à l'aide de la HashSet<string>?

Est-il mieux, par exemple, créer un Dictionary<string, object> qui crée un nouvel objet de verrouillage pour chaque instance de chaîne?


Final De Mise En Œuvre

Sur la base des suggestions, je suis allé avec la mise en œuvre suivants:

public class Foo
{
    private readonly string _s;
    private static readonly ConcurrentDictionary<string, object> _locks = new ConcurrentDictionary<string, object>();

    public Foo(string s)
    {
        _s = s;
    }

    public void LockMethod()
    {
        lock(_locks.GetOrAdd(_s, _ => new object()))
        {
            ...
        }
    }
}
  • Je les bizarreries de l'aide d'un string comme le verrouillage de la cible dans ma réponse ici.
  • Puis-je suggérer un léger changement? de verrouillage(_locks.GetOrAdd(_s, s => new object())) Ce qui le rend si vous ne créez un objet par chaîne, au lieu d'en créer un à chaque fois que vous appelez LockMethod().
  • Concernant les problèmes d'inégalité des instances de chaîne mentionné à la fois par le JonSkeet et BrianGideon, je vous suggère de l'aide lock(_locks.GetOrAdd(String.Intern(_s), s => new object())), bien que le stage peut encore être désactivé via CompilationRelaxations.NoStringInterning et puis cela ne fonctionne pas, soit. Peut-être, à l'aide de la chaîne de hashcode comme un élément clé dans le dictionnaire serait de l'aide ici?!
  • un stage est un problème lorsque vous le verrouillage d'une chaîne de caractères (quelqu'un d'autre peut le verrou sur la même interné instance de chaîne). Ici, nous verrou sur une nouvelle instance de l'objet, et non pas sur la chaîne de l'instance. Personne d'autre n'a accès à cette nouvelle instance de l'objet.
InformationsquelleAutor Zaid Masud | 2012-10-09