java tableau thread-safety
Existe-il des problèmes de concurrence d'accès avec un fil de la lecture à partir d'un index d'un tableau, tandis qu'un autre thread écrit à un autre indice de la matrice, aussi longtemps que les indices sont différents?
par exemple (dans cet exemple, pas nécessairement recommandé pour une utilisation réelle, uniquement pour illustrer mon point de vue)
class Test1
{
static final private int N = 4096;
final private int[] x = new int[N];
final private AtomicInteger nwritten = new AtomicInteger(0);
//invariant:
//all values x[i] where 0 <= i < nwritten.get() are immutable
//read() is not synchronized since we want it to be fast
int read(int index) {
if (index >= nwritten.get())
throw new IllegalArgumentException();
return x[index];
}
//write() is synchronized to handle multiple writers
//(using compare-and-set techniques to avoid blocking algorithms
//is nontrivial)
synchronized void write(int x_i) {
int index = nwriting.get();
if (index >= N)
throw SomeExceptionThatIndicatesArrayIsFull();
x[index] = x_i;
//from this point forward, x[index] is fixed in stone
nwriting.set(index+1);
}
}
edit: critiquer cet exemple n'est pas ma question, j'ai littéralement veux juste savoir si d'accès au tableau à un indice, parallèlement à l'accès d'un autre indice, pose des problèmes de concurrence d'accès, ne pouvait pas penser à un exemple simple.
Vous devez vous connecter pour publier un commentaire.
Alors que vous ne serez pas obtenir un état non valide par la modification des tableaux comme vous le mentionnez, vous aurez le même problème qui se produit lorsque deux threads sont de la visualisation d'un non volatile entier sans synchronisation (voir la section Java Tutoriel sur la Consistance De La Mémoire Des Erreurs). Fondamentalement, le problème est que le Thread 1 peut écrire une valeur dans l'espace i, mais il n'y a aucune garantie quand (ou si) le Thread 2 va voir le changement.
La classe
java.util.de façon concomitante.atomique.AtomicIntegerArray
est-ce que vous voulez faire.L'exemple a beaucoup de choses qui diffère de la prose question.
La réponse à cette question est que les différents éléments d'un tableau sont accessibles indépendamment, de sorte que vous n'avez pas besoin de synchronisation si deux threads changer les différents éléments.
Cependant, la Java du modèle de mémoire ne garantit pas (que je sache) que la valeur d'un écrit par un thread sera visible par un autre thread, à moins que vous synchroniser l'accès.
En fonction de ce que vous êtes vraiment essayer de l'accomplir, il est probable que
java.util.concurrent
a déjà une classe qui va le faire pour vous. Et si ça ne marche pas, je recommande toujours de prendre un coup d'oeil au code source deConcurrentHashMap
, depuis votre code semble être en train de faire la même chose qu'elle fait pour gérer la table de hachage.Je ne suis pas vraiment sûr si la synchronisation seuls les
write
méthode, tout en laissant laread
méthode unsychronized serait de travailler. Pas vraiment quelles sont toutes les conséquences, mais au moins, elle pourrait conduire àread
méthode retournant quelques valeurs qui a simplement été remplacé par deswrite
.Oui, comme de la mauvaise cache entrelacement peut encore se passer dans un multi-cpu/core environnement. Il ya plusieurs options pour l'éviter:
Depuis read() n'est pas synchronisé, vous pourriez avoir le scénario suivant:
Puisque vous voulez vous assurer que votre variable d'adresses entrent jamais en conflit, ce sujet de quelque chose comme l'actualisation de la matrice de problèmes d'index):