2010-07-29 11 views
18

J'ai une liste chaînée samples:LinkedList est-il compatible avec les threads lorsque j'y accède avec offre et sondage exclusivement?

protected LinkedList<RawDataset> samples = new LinkedList<RawDataset>(); 

J'insérer un élément dans la liste en fil 1 comme ceci:

this.samples.offer(data); 

Et je récupérer des éléments de dans un second fil comme so:

public RawDataset retrieveSample() { 
    return this.samples.poll(); 
} 

Est-ce que cela peut être considéré comme un thread sécurisé? Même si les threads 1 et 2 modifient tous deux la liste, ils ne le font que sur la tête ou la queue de la liste, n'est-ce pas?

Si ce n'est pas le cas, quelqu'un peut-il me diriger vers une classe de l'API Java qui est fournie avec poll/offer et est sûre d'être thread-safe?

Merci d'avance.

BTW: Collections.synchronizedList(new LinkedList()) ne me donnera pas accès à offer/poll.

+1

Méthodes '' offer' et poll' sont en fait Declard dans l'interface 'Queue', qui est implémenté par LinkedList en plus des interfaces List. C'est pourquoi ces méthodes ne sont pas disponibles dans le résultat de Collections.synchronizedList. –

Répondre

31

LinkedList n'est pas compatible avec les unités d'exécution. Vous devriez faire le verrouillage vous-même. Au lieu de cela, essayez ConcurrentLinkedQueue ou LinkedBlockingDeque à la place si cela correspond à vos besoins, ils sont thread sûr, mais un comportement légèrement différent de LinkedList.

+0

Que dois-je faire, si je veux avoir une file d'attente liée de taille maximale, de sorte que si un nouvel élément est inséré et que nous atteignons le maximum, le plus ancien sera supprimé (pas de blocage, car cela n'est pas nécessaire)? J'en ai besoin pour un journal des derniers X événements. Devrais-je simplement utiliser le LinkedList normal, et utiliser "synchronized" dessus? Ou y a-t-il une structure de données concurrente sympa pour cela? –

+0

@androiddeveloper Cela ressemble à une file d'attente circulaire, vous devriez poser une question ici sur stackoverflow à propos de cela ne pas ajouter un commentaire à une vieille question. – nos

+0

Oui, j'ai eu le sentiment que c'était son nom, mais y a-t-il une implémentation intégrée pour cela, c'est sûr pour les threads? –

8

Si vous avez un JDK, vous pouvez consulter le code source de "Collections.synchronizedList()". C'est simple, vous pouvez donc créer une copie de cette méthode spécialisée pour obtenir à la fois les fonctions LinkedList et de synchronisation.

public class SynchronizedLinkedList<T> implements List<T> { 

    private LinkedList<T> list; 

    private Object lock; 

    public void add(T object) { 
     synchronized(lock) { 
      list.add(object); 
     } 
    } 

    // etc. 
} 
+2

J'ai généralement tendance à préférer les classes existantes à la mise en place de la mienne. Donc, je vais aller avec l'une des deux autres suggestions. Mais merci quand même. –

+6

Pourquoi introduisez-vous un objet verrou supplémentaire si vous pouvez simplement synchroniser sur l'objet mutable-la liste elle-même? –

1

C'est correct - LinkedList n'est pas synchronisé et donc pas thread-safe. Si vous ne souhaitez pas utiliser les nouvelles analogies synchronisées de LinkedList, à savoir, ConcurrentLinkedQueue ou LinkedBlockingQueue, vous pouvez initialiser LinkedList comme ceci:

LinkedList<RawDataset> samples = (LinkedList)Collections.synchronizedList(new LinkedList<RawDataset>()); 
+4

Cela peut fonctionner dans certains environnements, mais il n'y a aucune garantie que la valeur renvoyée par 'Collections.synchronizedList() 'peut toujours être converti en' LinkedList'. En général, si vous devez lancer, vous devez repenser votre conception. –