Ai-je besoin de synchronisation supplémentaire lors de l'utilisation d'un BlockingQueue?
J'ai un simple haricot @Entity Message.java qui a des propriétés standard. Le cycle de vie de l'objet est comme suit
Instanciation de Message arrive sur le Thread A, qui est ensuite mis en file d'attente dans un blockingQueue
Un autre thread à partir d'un pool obtient de l'objet et faire des trucs avec elle, et les changements de l'état de Message, après que, l'objet entre de nouveau dans la blockingQueue. Cette étape est répétée jusqu'à ce qu'une condition d'arrêt. Chaque fois que l'objet devient de lecture/écriture est potentiellement à partir d'un autre thread, mais avec la garantie qu'un seul thread à la fois de la lecture/écriture à elle.
Donné les circonstances, j'ai besoin de synchroniser les getters/setters ? Peut-être que les propriétés volatiles ? ou puis-je simplement laisser sans synchronisation ?
Merci et j'espère que je pourrais clarifier ce que je suis ici.
Vous devez vous connecter pour publier un commentaire.
Non, vous n'avez pas besoin de synchroniser l'accès aux propriétés de l'objet, ou même utiliser
volatile
sur les variables de membre.Toutes les actions effectuées par un fil avant de files d'attente d'un objet sur un
BlockingQueue
"se passe-avant" l'objet est retiré. Cela signifie que toutes les modifications apportées par le premier thread sont visibles à la seconde. C'est un comportement commun pour les collections simultanées. Voir le dernier paragraphe de leBlockingQueue
de documentation de classe.Aussi longtemps que le premier thread n'a pas d'effectuer des modifications après la mise en attente de l'objet, il sera en sécurité.
Vous n'avez pas besoin de faire la synchronisation de vous-même, parce que la file d'attente est-il pour vous déjà.
La visibilité est également garanti.
Si vous êtes sûr qu'un seul thread à la fois accéder à votre objet, vous n'avez pas besoin de synchronisation.
Cependant, vous pouvez vous assurer qu'en utilisant le mot-clé synchronized: chaque fois que vous souhaitez accéder à cet objet et assurez-vous qu'aucun autre thread n'est en utilisant le même exemple, vous envelopper d'un code dans un bloc synchronisé:
Synchronisée bloc d'acquérir un implicite de verrouillage sur le monannonce objet. Donc, pas d'autres synchronisé bloc auront accès à la même instance jusqu'à la sortie de ce bloc.
Ça serait comme si on pouvait laisser de la synchronisation hors les méthodes. Le synchronisée suffit de verrouiller l'objet pour permettre à un seul thread pour y accéder. Vous avez déjà géré que par le blocage de la file d'attente.
Volatils serait bon de l'utiliser, car cela permettrait de garantir que chaque thread dispose de la dernière version, au lieu d'un thread local de la valeur du cache.
volatile
avec unBlockingQueue
est inutile (et de l'inefficacité d'un double emploi); une partie de laBlockingQueue
contrat, c'est que toutes les actions qu'à un fil avant de mettre en file d'attente-ing un objet "se passe-avant" l'objet est retiré par un autre thread.