0
votes

Comment gérer la synchronisation des arrais en Java

J'ai un objet avec un éventail d'entiers et une méthode qui peut le modifier, verrouillant juste un élément de mon tableau: xxx

alors je voudrais calculer la moyenne de mon Array, mais pour faire cela, j'ai besoin de "verrouiller" l'objet entier et assurez-vous que les autres threads n'exécutent pas la méthode SetInteger, jusqu'à la fin de mon calcul de ma calcul. Comment puis-je faire cela?

Si j'écris: synchronisé (myObject) {...} Cela ne fonctionnera pas parce que je verrouille différentes choses ...


0 commentaires

3 Réponses :


1
votes

Votre approche actuelle ne fonctionne pas; Vous ne bloquez pas myARRAY mais un objet entier entier qui a été référé de celui-ci; Un autre thread peut voir les mises à jour hors de l'ordre ou ne pas voir les mises à jour pendant un moment ou du tout.

Il y a une meilleure solution - déclarer myarray comme atomicintegerarray myarray; . Mises à jour de atomicintegerarray est toujours correctement synchronisé; D'autres threads sont garantis pour les voir immédiatement et dans le bon ordre.

C'est encore mieux (plus efficace) si vous pouviez distribuer le travail entre les threads de manière à ne pas mettre à jour les mêmes éléments du tableau - il y a toujours un certain coût associé à la synchronisation de fil.


1 commentaires

Si mon tableau est un éventail d'objets appelés Stonks au lieu d'entiers, serait synchronisé (MyARRAY [POSITION]) SOIT OK? Je veux dire, si d'autres threads veulent éditer un stonk, il faut verrouiller que Stonk spécifique et non tous le tableau de Stonks



-1
votes

Utilisez un verrou en lecture en lecture. N'oubliez pas que vous devez lire le verrouillage pour lire le tableau pour calculer la moyenne, etc. et le verrouillage de l'écriture pour mettre à jour le tableau.

aucun point sur l'optimisation de la synchronisation sur un seul élément. Cette approche échouerait.

Il existe des moyens plus complexes d'optimiser, tels que la segmentation de la matrice dans de nombreux verrous, etc., mais pour toutes les fins pratiques n'est pas nécessaire.

Readwrite Lock Javadoc


0 commentaires

0
votes

Tout d'abord, la synchronisation de votre setarray ne va pas empêcher les conditions de course. Le problème est qu'il remplace l'objet que d'autres threads se synchronisent avec un autre. En conséquence, ils sont susceptibles de se synchroniser sur différents objets.

Donc, si vous avez vraiment besoin de la synchronisation à grain fin (c'est-à-dire de la synchronisation de certains d'autres de votre application, vous devrez alors repenser la façon dont vous le faites. atomicintegerarray pourrait être la réponse; Voir Javadoc .


Maintenant au problème: obtenir l'exclusion mutuelle sur l'ensemble de la matrice afin que vous puissiez calculer la moyenne. ( atomicintegerarray ne résoudra pas ce problème!)

Si nous ignorons le verrouillage au niveau des cellules, la (les) solution (s) pour cela est simple. Vous venez d'obtenir une exclusion mutuelle sur l'ensemble de la matrice lorsque vous devez le mettre à jour et chaque fois que vous devez accéder à une cellule unique ou à toutes les cellules.

Mais cela rend toutes les opérations de tableau un goulot d'étranglement concurrentiel, ce que vous essayez probablement d'éviter.

Mais cela signifie que tous les autres threads qui doivent obtenir une exclusion mutuelle sur tout le tableau ou juste une seule cellule de la matrice doivent utiliser la même exclusion mutuelle mécanisme. Atteindre une matrice complète et une exclusion cellulaire unique dans le même mécanisme deviennent difficultés ... et très coûteux par rapport à synchronisé (tableau) .

Une meilleure idée serait de le réaliser à un niveau supérieur. Par exemple, utilisez un readwrite verrouillage avec des verrous "Lire" représentant la possibilité de gagner une serrure de niveau de cellule 1 et l'écluse "écriture" à l'exclusion de tous les serrures de niveau de cellule . (Tous les filets avec les serrures "Lecture" devraient les libérer avant que le fil de la moyenne ne puisse faire son travail.)


Alternativement, demandez-vous ceci: Cela a-t-il un sens de la perspective de l'application pour calculer une moyenne précise de l'ensemble de la matrice alors qu'elle est mutée? Quelle est l'utilisation pratique de la moyenne, étant donné qu'elle ne pouvait être valable que pour un instant?

Peut-être que cela signifie que vous devez calculer la moyenne sans verrouillant le tableau et accepter qu'il est peu probable d'être instantanément précis. Ou si la moyenne doit être instantanément exacte, utilisez une atomique longue pour maintenir la somme de tous les éléments de réseau et que vous avez la matrice SET Opérations met à jour la somme.


1 - Vous pouvez également représenter la possibilité de muté la matrice à l'aide de atomicintegerarray Opérations.


0 commentaires