2015-06-25 12 views
12

Le implementazioni java.util.stream.Collectors::joining sono thread-safe? Posso fare qualcosa comeCollectors.joining (",") thread-safe?

public final class SomeClass { 
    private static final Collector<CharSequence, ?, String> jc = Collectors.joining(","); 

    public String someMethod(List<String> someList) { 
     return someList.parallelStream().collect(jc); 
    } 
} 

senza paura di incorrere in problemi di concorrenza?

+4

Da quello che ricordo non è responsabilità dei Collettori gestire la sicurezza del filo. I collezionisti forniscono semplicemente il modo di spiegare * dove * raccogliere, ma è Stream che gestisce * quando * raccogliere (che dovrebbe anche essere thread-safe). – Pshemo

+1

@Pshemo In questo caso più flussi utilizzano lo stesso programma di raccolta condiviso. – assylias

+1

@Pshemo guarda all'implementazione sembra funzionare - non so se è specifico per questo raccoglitore o se è un risultato derivato della sicurezza del thread. – assylias

risposta

11

È possibile utilizzare questo collettore come qualsiasi altro collettore fornito nella classe Collectors senza timore di incorrere in problemi di concorrenza. Il Collector non deve preoccuparsi della sicurezza del thread se non ha la caratteristica CONCURRENT. Ha solo bisogno di avere le sue operazioni non interferenti, apolidi e associativi. Il resto sarà fatto dalla stessa pipeline Stream. Utilizzerà le funzioni del collector nel modo in cui non richiede la sincronizzazione aggiuntiva. In particolare quando viene chiamata la funzione accumulator o combiner, è garantito che nessun altro thread stia operando sullo stesso valore accumulato al momento. Questo è specificato in Collector documentazione:

biblioteche che attuano la riduzione in base a Collector, come ad esempio Stream.collect(Collector), devono rispettare i seguenti vincoli:

< ...>

  • Per non collettori concorrenti, qualsiasi risultato restituito dal fornitore del risultato, dall'accumulatore o dalle funzioni del combinatore deve essere limitato in serie. Ciò consente che la raccolta si verifichi in parallelo senza che lo Collector debba implementare alcuna sincronizzazione aggiuntiva. L'implementazione della riduzione deve gestire che l'input sia partizionato correttamente, che le partizioni siano elaborate in modo isolato e che la combinazione avvenga solo dopo che l'accumulo è stato completato.

noti che il collettore stesso è stateless e funzioni fornisce, quindi è anche sicuro di avere nel campo statico. Lo stato viene conservato nell'accumulatore esterno che viene restituito da supplier e restituito a accumulator, combiner e finisher. Quindi, anche se lo stesso raccoglitore viene riutilizzato da diverse operazioni di flusso, non interferiscono.

+0

ottima risposta, è molto generico – voho

Problemi correlati