2009-11-13 6 views
1

Il est prudent de supposer que travailler avec un objet immuable ou le contourner serait toujours threadsafe?Les objets immuables sont-ils toujours threadsafe?

+0

Define « travailler avec ». L '"objet" lui-même peut être immuable (par exemple, un 'string' est immuable), mais une référence à one (' string myString = "..." ') ne garantit pas la sécurité des threads. Lequel demandez-vous? –

Répondre

9

Oui. Si un objet est vraiment immuable, sans mutations internes se produisant, alors l'objet lui-même sera threadsafe.

(Que vous gérez l'objet et le passer autour d'une manière threadsafe est une autre affaire!)

Qu'est-ce que je veux dire par « mutations internes »?

De nombreux objets semblent être immuables de l'extérieur - par exemple, aucun setters de propriété ou d'autres membres qui évidemment mutations de déclenchement - mais cela ne signifie pas que les internes privés de l'objet ne sont pas capables de en changeant.

C'est pourquoi il est important de documenter la mutabilité et la sécurité des threads de vos objets et/ou de leurs membres. Sinon, les consommateurs de votre objet ne peuvent pas le découvrir sans examiner de près les éléments internes (qui sont un détail de mise en œuvre et peuvent changer à tout moment).

+0

Que voulez-vous dire "mutations internes"? –

+0

Lorsque la classe modifie en interne la valeur de lui-même. –

+0

si l'objet ne change pas lui-même – RvdK

2

Cela dépend de ce que vous entendez par threadsafe; comme le souligne Eric Lippert's blog, le terme peut signifier plusieurs choses. Les objets immuables garantissent que peu importe quand vous accédez à une propriété ou à une méthode sur une instance donnée, le résultat sera toujours le même; C'est la sécurité des threads dans cette instance. Cependant, si vous avez un champ mutable contenant une référence à un objet immuable, alors plusieurs appels via le même champ peuvent ne pas être à la même instance, donc ne sont pas cohérents (c'est-à-dire "threadsafe").

Je suppose que pour la signification de "threadsafe" que vous avez en tête, la réponse est oui. Mais gardez à l'esprit que les objets immuables ne sont pas une balle d'or; ils ne vous immunisent pas aux interactions de threads, ils fournissent simplement la cohérence à travers une seule instance.

+1

Un autre article pertinent: http://blogs.msdn.com/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx – LukeH

1

Pour répondre correctement à la question: Non

Vous ne pouvez pas supposer que les objets immuables sont toujours threadsafe.

Mais le plus probablement le sont. Voir aussi la discussion sur la réponse de Lukes. Par exemple: l'accès aux méthodes ou aux getters de propriété pourrait déclencher l'initialisation, ce qui n'est pas connu par l'appelant. (Par exemple, initialisation paresseuse) Cette initialisation doit être implémentée explicitement par threadsafe.

0

D'abord, l'objet doit être vraiment immuable - pas seulement l'interface publique, mais tout l'état interne doit être initialisé. Cela interdit par ex. "Obtenir une fois puis cache" ou initialisation différée. Deuxièmement, pendant la construction, les objets sont modifiés - et en raison des optimisations et de la réorganisation des instructions sur la CPU, l'ordre dans lequel la mémoire est écrite n'est pas nécessairement le même que celui que vous voyez dans le code source.

Cela signifie que, sans synchronisation, un autre thread peut déjà voir une référence valide à l'objet avant qu'il ne soit entièrement construit.

Je ne connais pas assez le modèle C# memroy vous dire exactement quelle synchronisation est nécessaire - peut-être quelqu'un d'autre peut aider (fait communauté wiki)