2016-03-29 5 views
1

Im Allgemeinen schreibe ich einen benutzerdefinierten Stromabnehmer, der mit einem Lieferanten, einem Akkumulator und einem Kombinator für mein Wissen kombiniert wird. In meinem Kundenkollektor merke ich, dass der Akkumulator nicht threadsicher ist, also setze ich den Combiner null und den Collector.CharacteristicsIDENTITY_FINISH. Die Codes können die Kompilierung bestehen, aber es gibt eine Laufzeitausnahme, da der Combiner nicht Null sein sollte, was bereits durch die NotNull-Annotation angezeigt wird.Wie kann ich einen benutzerdefinierten Stream-Collector in Java 8 einen einzelnen Thread verwenden, um die Verarbeitung zu tun?

Meine Frage ist, wenn ich einen Combiner in meinem Kollektor mit Collector.Characteristics sein, IDENTITY_FINISH, wird der Akku parallel laufen (oder gleichzeitig) oder nur in einem einzigen Thread ohne Rennen Problem?

+0

Wenn Sie nicht möchten, dass Ihr Collector parallel verwendet wird, können Sie beim Implementieren des Combiners eine Ausnahme auslösen, aber solange Sie das Merkmal CONCURRENT nicht melden, muss der Akkumulator kein Thread sein -sicheres AFAIK. –

Antwort

4

Sie können null nicht für jede Funktion verwenden, die im Kollektor verwendet wird (einschließlich Lieferant, Akkumulator, Kombinator und Finisher). Die gemeinsame Lösung, wenn Sie keinen geeigneten Kombinierer bereitstellen kann, ist ein Wurf Lambda passieren:

(a, b) -> {throw new UnsupportedOperationException("Combining is not supported");} 

Danach können Sie Ihre Collector verwenden können. Obwohl dies immer noch eine schlechte Praxis ist, erlaubt es die Schnittstelle Collector nicht, den Kombinierer nicht zu implementieren.

Bitte beachten Sie, dass Sie sich nicht um die Thread-Sicherheit kümmern müssen, es sei denn, Sie geben explizit das Merkmal CONCURRENT an. Wenn Ihr Kollektor nicht gleichzeitig ist, wird der parallele Strom den Lieferanten in separaten Threads aufrufen, dann den Akkumulator dort unabhängig verwenden und schließlich den Kombinierer aufrufen, nachdem die gesamte Akkumulation beendet ist. Es ist der springende Punkt bei Sammlern: Es ist garantiert, dass für nicht-gleichzeitige Sammler Sie nicht die Thread-Sicherheit benötigen, keine gleichzeitige Operationen mit dem gleichen Container durchgeführt werden. Deshalb ist ein Lieferant notwendig: Er könnte mehrmals aufgerufen werden, um mehrere unabhängige Container für jeden Thread zu erstellen. Wenn Sie keinen Finisher haben, müssen Sie IDENTITY_FINISH nicht explizit angeben. Verwenden Sie einfach

Collector<?,?,?> myCollector = Collector.of(mySupplier, myAccumulator, myCombiner); 

Die IDENTITY_FINISH Charakteristik automatisch hinzugefügt werden.

Verwandte Themen