2011-06-29 6 views
0

J'utilise une bibliothèque externe dans Android qui a une ArrayList d'objets à laquelle on accède à partir d'un autre thread. Mon problème est que je voudrais déplacer certains objets de cette AarrayList d'une manière qui ne provoque pas d'exception nulle sur l'autre thread. Donc, ce que je veux faire est: J'ai une ArrayList ABCDEFGH, et je veux déplacer F de sa position actuelle à la première position, ainsi ArrayList deviendra FABCDEGH. Notez que je ne peux pas utiliser swap pour cela car tous les autres objets sont déplacés correctement.Quelle est la meilleure façon de déplacer un objet sur un thread ArrayList en toute sécurité?

Une implémentation naïve est:

list.remove(F); 
list.add(0,F); 

Mais cette cause de la mise en œuvre exception nulle de l'autre fil parce que l'autre thread est en boucle la liste en boucle comptée écrite à la main, à cause de la condition de la course la boucle de fil peut courir entre la suppression et l'ajout de F. Je ne peux pas rendre la bande de roulement ArrayList sûre parce que je n'ai pas accès à la bibliothèque externe.

Y a-t-il une meilleure façon de faire ce mouvement (de n'importe quelle position à n'importe quelle position de l'Arraylist) sans condition de course? Notez que la taille de ArrayList ne sera pas modifiée.

+0

Possédez-vous le code qui fait la boucle et le supprimer/ajouter? Ou la boucle s'exécute-t-elle dans le code de la bibliothèque? – sudocode

+0

La boucle s'exécute sur le code de la bibliothèque – Akira

Répondre

3

Si vous possédez la boucle et le code d'échange, vous pouvez synchroniser les deux opérations dans la liste.

// code for loop 
for (int i = 0; i < length; i++) { 
    synchronized(list) { 
    letter = list.get(i); 
    } 
    // whatever else 
} 

// code for swap 
synchronized(list) { 
    list.remove(F); 
    list.add(0,F); 
} 

Mise à jour

Je suppose que vous avez besoin du fil de boucle pour voir les modifications que vous apportez dans votre échange/code boucle. Est-ce exact? Si ce n'est pas le cas, vous pouvez simplement copier/copier la liste pour votre usage personnel.

List copy = new ArrayList(list); 
copy.remove(F); 
copy.add(0,F); 
+0

Salut sudocode, je ne possède pas le code de boucle, seulement le swap (c'est un mouvement, pas un swap). Si je synchronise seulement le swap, est-ce que j'ai toujours la condition de course? Merci – Akira

+0

Si vous ne possédez pas le code de boucle, et il ne se synchronise pas sur la liste, vous ne pouvez pas modifier la liste sur votre propre thread en toute sécurité. – sudocode

0

réordonner les objets dans la liste de tableaux, mais sans utiliser add(), remove() ou toute autre méthode qui peut modifier la taille.

Il peut être fait, plutôt inélégante, comme suit:

Object temp = F; 

for (int i = list.indexOf(F); i > 0; i--) { 
    list.set(i, list.get(i - 1)); 
} 

list.set(0, temp); 

Notez, cependant, que la boucle dans l'autre thread peut rencontrer les objets dans le mauvais ordre, ou le même objet à différentes positions. Et si l'autre thread ajoute ou supprime des éléments, cela ne fonctionnera pas.

Je pense que si vous ne pouvez pas synchroniser la liste, vous ne devriez peut-être pas essayer de le modifier à partir de votre thread.

Questions connexes