2011-04-14 5 views
3

en Java, j'ai un large éventail de chaînes.mises à jour simultanées sur un tableau en Java

J'ai un fil faire quelque chose comme ceci:

for (int i=0;i<10000;i++) array[i] = getSomeValue(); 

J'ai un autre thread faire quelque chose comme ceci:

for (int i=10000;i<20000;i++) array[i] = getSomeValue(); 

et un autre thread faire:

for (int i=20000;i<30000;i++) array[i] = getSomeValue(); 

et ainsi sur.

dois-je faire quelque chose de spécial pour faire cette opération?

cela fonctionnera-t-il?

Je tente de remplir ce grand tableau plus rapidement en divisant la tâche en plusieurs threads, mais je me demande si c'est la bonne chose à faire.

Je travaille avec une machine 64 bits 16 cpus et toutes les choses de fantaisie.

+0

Si vous avez de la malchance, vous pouvez rencontrer un problème de simultanéité si chaque thread essaye de redimensionner le tableau en même temps. Si vous connaissez déjà le nombre total d'éléments à ajouter, vous devez créer votre tableau de cette taille. – Parvez

Répondre

8

Votre code fonctionnera correctement.

Différentes parties d'une matrice sont indépendantes les unes des autres.

Le spec dit:

Une considération de mise en œuvre pour les machines virtuelles Java est que chaque élément de champ et le réseau est considéré comme distinct

+1

pas tout à fait vrai: cela dépend de ce qu'il veut faire avec le tableau quand il a fini (il faut s'assurer que les mises à jour sont visibles pour les futurs consommateurs du tableau). – jtahlborn

+1

C'est un problème distinct, jtahlborn. – DJClayworth

+0

@DJClayworth - comment est-ce un problème distinct? la question est de savoir si ce code est correct. pour moi, "correct" signifie que vous pouvez utiliser les résultats dans votre code. la seule façon d'utiliser les résultats du code de l'OP dans son programme est s'il gère correctement la visibilité du fil. assez inutile pour initier le tableau et ne pas être en mesure de le lire plus tard. – jtahlborn

0

Il devrait être bien moins getSomeValue() a des effets secondaires qui changent mutable indiquer que plusieurs threads accèdent. S'il n'y a pas de changement d'état, alors vous êtes défini. Vous n'accéderez pas au même morceau de mémoire dans aucune des boucles.

La rapidité ou non dépendra de la configuration matérielle et de l'implémentation de votre thread.

1

Cela devrait fonctionner correctement. Cependant, si vous voulez être sûr que c'est sûr, vous pouvez remplir différents tableaux dans chaque thread, puis System.arraycopy() les dans un grand tableau.

0

Tant que chaque thread travaille sur un segment spécifique du tableau, les mises à jour doivent être correctes. Additionnellement, vous pouvez certainement voir un coup de pouce en divisant le travail. Vous aurez probablement envie de tester le niveau de l'amélioration, en testant avec un nombre différent de threads. Probablement devrait commencer à 16 ans puisque vous avez 16 CPU, et voir comment augmenter et diminuer les performances des effets.

Un problème que vous pourriez avoir est avec la visibilité. Je ne crois pas que les éléments du tableau soient garantis par tous les threads car ils ne sont pas volatiles. Donc, si les sections du tableau doivent être accessibles par plusieurs threads, vous pourriez avoir un problème. Une façon de gérer cela est d'utiliser un AtomicIntegerArray ... AtomicReferenceArray.

1

vous pouvez initier le tableau en toute sécurité avec ce code, cependant tout code qui doit utiliser le tableau doit ensuite être correctement synchronisé avec les threads qui effectuent les mises à jour initiales. Cela peut être aussi simple que de "joindre" tous les threads init avant d'utiliser le tableau.

0

Avec Java 8, cela est devenu beaucoup plus facile:

Arrays.parallelSetAll(array, i -> getSomeValue()); 

Cela devrait également résoudre les problèmes de visibilité mentionnés dans d'autres réponses et commentaires.

Questions connexes