java simultanées de la Liste du réseau d'accès
J'ai un objet qui est un singleton. Cet objet déclare:
List<Player> players = new ArrayList<Player>();
Le même objet spécifie également les 4 opérations sur cette liste de tableaux:
public List<Player> getPlayers() {
return players;
} //the result of this method can be used in another object as an iterator (or maybe by index-access)
et
public void removePlayer(Player player) {
players.remove(player);
}
public void addPlayer(Player player) {
players.add(player);
}
public boolean isPresent(Player player) {
if (players.constans(player)) {...
}
Maintenant dans le constructeur, je le fais comme ça:
players = Collections.synchronizedList(new ArrayList<Player>());
Mais quelle est la bonne façon de synchroniser ces méthodes. Il semble comme si j'utilise un itérateur dans une autre classe, il sera encore au travers de la modification simultanée d'exception. L'exception se passerait si une 2 threads appeler en même temps les "supprimer" et "contient" méthode? Il existe plusieurs threads d'accéder à l'singleton, donc je voudrais savoir la méthode pour ce faire avec le minimum d'impact sur la performance.
Comme l'a expliqué tieTYT, chaque accès à la liste doivent être synchronisés. C'est un objectif utopique. Donc, vous ne devriez pas laisser quelqu'un d'accéder à la liste de l'extérieur de votre classe. Ou vous devez utiliser une liste concurrente à la place.
L'utilisation simultanée de l' "contient" et "supprimer" lever une exception?
Si cela est acceptable, vous pouvez retourner une copie de la liste, vous pouvez même retourner inmodifiable copie de la liste pour vous assurer que tout changement d'échouer avec l'exception. Pour les gars qui pensent qu'ils peuvent ajouter des objets sans l'aide de votre API.
Non, parce que ces méthodes sont synchronisés. Mais dès que vous réitérer, ou de faire un check-puis-loi sur l'opération comme
Pour d'autres options, voir stackoverflow.com/questions/207829/...
L'utilisation simultanée de l' "contient" et "supprimer" lever une exception?
Si cela est acceptable, vous pouvez retourner une copie de la liste, vous pouvez même retourner inmodifiable copie de la liste pour vous assurer que tout changement d'échouer avec l'exception. Pour les gars qui pensent qu'ils peuvent ajouter des objets sans l'aide de votre API.
Non, parce que ces méthodes sont synchronisés. Mais dès que vous réitérer, ou de faire un check-puis-loi sur l'opération comme
if (!list.contains(foo)) list.add(foo)
, vous avez besoin explicite de la synchronisation. Aussi méfiez-vous de caché itérations comme dans new ArrayList<>(list)
.Pour d'autres options, voir stackoverflow.com/questions/207829/...
OriginalL'auteur Artem Moskalev | 2013-07-10
Vous devez vous connecter pour publier un commentaire.
La documentation répond à votre question.
Comme pour
contains
etremove
, vous ne devriez pas avoir à synchroniser manuellement. Je suis en train de regarder le code source deCollections
et on dirait qu'il le fait pour vous:Il ne serait pas synchronisés liste si vous avez à faire ce genre de choses sur votre propre.
dans la documenation il a déclaré
Iterator i = list.iterator(); // Must be in synchronized block
. Et oui, mon +1 à votre question, il semble logique quesynchronizedList
est prévu pour faire le travailOriginalL'auteur Daniel Kaplan
Si vous ne prévoyez pas de le mettre à jour souvent utiliser un CopyOnWriteArrayList sinon @tieTYT la suggestion de travaux.
Vous pouvez également gérer vous-même en retournant une copie de la liste au lieu de la liste réelle au sein de la
getPlayers
. (Si vous utilisezCollections.synchronizedList
)Cela a pour effet de bord d'une liste de date après un ajout/suppression se fait
Edit: Voler Grzegorz suggestion pour
unmodifiableList
OriginalL'auteur John Vint