Bonne façon de synchroniser la liste de tableaux en java
Je ne suis pas sûr si c'est le bon moyen de synchroniser mon ArrayList
.
J'ai un ArrayList
in_queue
qui est transmis à partir de la registerInQueue
fonction.
ArrayList<Record> in_queue = null;
public void registerInQueue(ArrayList in_queue)
{
this.in_queue = in_queue;
}
Maintenant, je suis en train de le synchroniser. Est-ce sychronizing mon in_queue
objet correctement?
List<Record> in_queue_list = Collections.synchronizedList(in_queue);
synchronized (in_queue_list) {
while (in_queue_list.size() > 0) {
in_queue_list.remove(0);
}
}
- Vous ne pouvez pas vraiment de mise à niveau, d'une liste synchronisée parce que vous êtes passé à une référence, de sorte que vous n'avez pas vraiment le posséder. Quelle que soit vous a donné la référence pourrait toujours modifier la liste initiale, il est passé à vous en même temps. Indépendamment de ce que la synchronisation vous permet d'ajouter, sauf si c'est explicitement connu que la liste va être gardé par sa intrinsèque de verrouillage.
- Je vais mettre un bloc synchronisé autour de toute opération sur la file d'attente. Merci!
Vous devez vous connecter pour publier un commentaire.
Vous synchronisez deux fois, ce qui est inutile et, éventuellement, ralentit le code: modifications lors de l'itération sur la liste besoin d'un synchronnization sur l'ensemble de l'opération, qui vous sont faites avec
synchronized (in_queue_list)
à l'Aide deCollections.synchronizedList()
est superflu dans ce cas (il crée un wrapper qui synchronise les opérations individuelles).Cependant, puisque vous êtes de vider complètement la liste, les itérées de suppression du premier élément est la pire façon possible de le faire, sice pour chaque élément tous les éléments suivants doivent être copiés, ce qui en fait un O(n^2) fonctionnement - horriblement lent pour les grandes listes.
Au lieu de cela, il suffit d'appeler
clear()
- pas d'itération nécessaire.Edit:
Si vous avez besoin de la seule méthode de synchronisation de
Collections.synchronizedList()
plus tard, c'est la façon correcte:Mais dans de nombreux cas, la seule méthode de synchronisation est insuffisant (par exemple, pour tous itération, ou lorsque vous obtenez une valeur, faire des calculs fondés sur elle, et de le remplacer par le résultat). Dans ce cas, vous devez utiliser la synchronisation manuelle de toute façon, donc
Collections.synchronizedList()
est juste inutile de surcharge supplémentaire.clear()
est un peu over-the-top, mais. 🙂À la recherche à votre exemple, je pense que ArrayBlockingQueue (ou ses frères et sœurs) peut être utile. Ils regardent après la synchronisation, pour vous, de sorte que les fils peuvent s'écrire de la file d'attente ou peek/prendre sans plus de synchronisation de travail sur votre partie.
Qui est correcte, et documenté:
http://java.sun.com/javase/6/docs/api/java/util/Collections.html#synchronizedList(java.util.Liste)
Cependant, pour effacer la liste, il suffit d'appeler Liste.clear().
Oui, c'est la façon correcte, mais le bloc synchronisé est nécessaire si vous voulez que tous les prélèvements ensemble pour être sûr - à moins que la file d'attente est vide, pas de suppressions permis. Ma conjecture est que vous voulez juste coffre-fort et de file d'attente file d'attente des opérations, de sorte que vous pouvez supprimer le bloc synchronisé.
Cependant, il y a beaucoup avancé simultanées files d'attente en Java comme ConcurrentLinkedQueue
Prenons une liste normale (mis en œuvre par la classe ArrayList) et synchronisés. Ceci est illustré dans le SynchronizedListExample classe.
Nous passons les Collections.synchronizedList une nouvelle méthode de liste de tableaux de Chaînes de caractères. La méthode renvoie un synchronisé Liste de Chaînes de caractères.
//C'est ici SynchronizedArrayList classe
Notez que lors de l'itération sur la liste, cet accès se fait toujours à l'aide d'un bloc synchronisé que les verrous sur la synchronizedList objet.
En général, une itération sur un synchronisé collection doit être fait dans un bloc synchronisé