2013-05-27 5 views
3

Je ne suis pas sûr de comprendre les listes synchronisées en Java. Supposons que je donne les résultats suivants:Comment fonctionnent les listes synchronisées?

List<Integer> numbers = Collections.synchronizedList(new ArrayList<Integer>()); 

// Assumption: This is running on a separate thread 
public void add() { 
     numbers.add(new Random().nextInt(100)); 
} 

// This is also running on a separate thread 
public void doSomething() { 
     synchronized(numbers) { 
      for (int i : numbers) {} 
     } 
} 

Fondamentalement, ce que le add() pouvoir ajouter des numéros à la liste si doSomething() est invoquée? Que se passerait-il si j'utilisais à la place public synchronized void add() et public synchronized void doSomething()?

Je travaille sur un serveur socket UDP, et j'allais stocker les clients dans un ArrayList. J'aurais plusieurs threads qui peuvent lire, écrire et modifier cette liste. Que devrais-je faire?

Répondre

2

est-ce que add() pourra ajouter des nombres à la liste si doSomething() est invoqué? Non, pas avant que le thread appelant doQuelquechose() ne quitte le bloc synchronisé. Que se passerait-il si j'utilisais à la place public void synchronisé add() et public void faitQuelquechose()?

En supposant que ce sont les seuls endroits où la liste est utilisée, l'effet serait le même. Mais vous synchroniseriez sur l'objet contenant la liste plutôt que de synchroniser sur la liste elle-même.

Fondamentalement, tous les accès à un état partagé doivent être synchronisés sur le même verrou. Vous choisissez la serrure que vous préférez. Au lieu d'utiliser une liste synchronisée ou des méthodes synchronisées, vous pouvez utiliser une collection concurrente comme une CopyOnWriteArrayList.

+0

Je suis confus; quelqu'un d'autre a dit le contraire. –

+1

@BrandonSmith - J'avais tort et j'ai changé ma réponse. –

+0

@BrandonSmith, cette réponse explique clairement votre comportement de code, puisque les deux opérations sont synchronisées sur le même objet dans les deux cas. – techuser

0

Cela devrait fonctionner correctement. Selon les documents pour Collections.synchronizedList, les méthodes de mutateur de liste (add(), etc.) se synchronisent sur l'objet liste lui-même. Puisque votre boucle d'itération est également à l'intérieur d'un bloc synchronized, tout devrait bien se passer.

+0

Que dois-je faire ensuite? –

+0

@@ BrandonSmith - Oubliez ma réponse précédente. Votre code est correct. –

+0

Je ne suis pas sûr de savoir ce que "votre code est bon" signifie. Pour l'énoncer explicitement, le add() ne sera pas capable d'ajouter des nombres à la liste si doSomething() est en cours de traitement. – techuser