Pas de. L' +=
opération n'est pas thread-safe. Il exige de verrouillage et / ou d'un bon fonctionnement de la chaîne de "passe-avant" les relations de toute expression impliquant la cession à une salle de champ ou un élément de tableau pour être thread-safe.
(Avec un champ déclaré volatile
, le "passe-avant" il existe des relations ... mais uniquement sur les opérations de lecture et écriture. L' +=
opération consiste en une lecture et une écriture. Ce sont individuellement atomique, mais la séquence n'est pas. Et la plupart d'affectation des expressions à l'aide de =
impliquent à la fois une ou plusieurs lectures (sur la droite) et une écriture. Cette séquence n'est pas atomique.)
Pour l'histoire complète, lire JLS 17.4 ... ou le chapitre de "la Java de la Simultanéité dans l'Action", par Brian Goetz et coll.
Comme je sais que les opérations de base sur les types primitifs sont thread-safe ...
En fait, c'est une prémisse inexacte:
- prenons le cas de tableaux
- considérer que les expressions sont généralement composés d'une séquence d'opérations, et qu'une séquence d'opérations atomiques n'est pas garanti d'être atomique.
Il y a un problème supplémentaire pour l' double
type. Le JLS (17.7) dit ceci:
"Pour l'application du langage de programmation Java modèle de mémoire, une seule écriture à un non-volatile long ou double valeur est traitée comme deux écritures: une pour chacune des moitiés de 32 bits. Il peut en résulter une situation où un thread voit les 32 premiers bits d'une valeur de 64 bits à partir d'une écriture, et la seconde de 32 bits à partir d'une autre écriture."
"Les écritures et les lectures de la volatilité de long et double les valeurs sont toujours atomique."
Dans un commentaire, il est demandé:
Donc, ce type que je devrais utiliser pour éviter de synchronisation globale, qui s'arrête à tous les threads à l'intérieur de cette boucle?
Dans ce cas (où vous êtes à la mise à jour d'un double[]
, il n'y a pas d'alternative à la synchronisation avec des serrures ou primitive mutex.
Si vous avez eu une int[]
ou long[]
vous pourriez les remplacer par AtomicIntegerArray
ou AtomicLongArray
et de faire usage de ces classes serrure-mise à jour gratuite. Cependant il n'y a pas d' AtomicDoubleArray
classe, ou même un AtomicDouble
classe.
(Mise à JOUR - quelqu'un a fait remarquer que la Goyave donne un AtomicDoubleArray
classe, de sorte que serait être une option. Bon, en fait.)
Une façon d'éviter un "verrouillage global" et le massif des problèmes de contention peut-être de diviser le tableau en nominal régions, chacune avec son propre cadenas. De cette façon, un thread ne doit bloquer un thread si elles sont à l'aide de la même région de la matrice. (Rédacteur unique / multiples verrous de lecteur pourrait aider aussi ... si la grande majorité des accès sont lit.)