AtomicInteger recordNumber = new AtomicInteger();
Files.lines(inputFile.toPath(), StandardCharsets.UTF_8)
.map(record -> new Record(recordNumber.incrementAndGet(), record))
.parallel()
.filter(record -> doSomeOperation())
.findFirst()
Bunu yazdığımda, haritadan sonra paralel yerleştirildiğinden, konuların sadece harita çağrısına çıkacağını varsaydım. Ancak dosyadaki bazı satırlar her yürütme için farklı kayıt numaraları alıyordu.
Akışların başlık altında nasıl çalıştığını anlamak için resmi Java akışı belgelerini ve birkaç web sitesini okudum .
Birkaç soru:
Java paralel akışı dayalı çalışır SplitIterator biz bu koleksiyonların paralel akışı dışarı inşa zaman LinkedList vb ArrayList gibi her koleksiyonu ile uygulanmaktadır, karşılık gelen bölme yineleyici yineleme koleksiyonunu bölünmüş için kullanılan ve edilecektir. Bu, paralelliğin neden haritanın sonucu yerine orijinal giriş kaynağı (Dosya satırları) düzeyinde (yani Record pojo) gerçekleştiğini açıklar. Anlayışım doğru mu?
Benim durumumda, girdi bir dosya GÇ akışıdır. Hangi bölünmüş yineleyici kullanılacak?
parallel()Boru hattına nereye yerleştirdiğimiz önemli değil . Orijinal giriş kaynağı her zaman bölünecek ve geri kalan ara işlemler uygulanacaktır.Bu durumda, Java, kullanıcıların orijinal kaynak dışında boru hattının herhangi bir yerine paralel işlem yapmasına izin vermemelidir. Çünkü, java akışının dahili olarak nasıl çalıştığını bilmeyenler için yanlış anlayış veriyor.
parallel()İşlem Stream nesne türü için tanımlanmış olacağını biliyorum ve bu nedenle, bu şekilde çalışıyor. Ancak, alternatif bir çözüm sunmak daha iyidir.Yukarıdaki kod snippet'inde, giriş dosyasındaki her kayda bir satır numarası eklemeye çalışıyorum ve bu yüzden sipariş edilmelidir. Ancak,
doSomeOperation()ağır ağırlık mantığı olduğundan paralel olarak uygulamak istiyorum . Ulaşmanın bir yolu kendi özelleştirilmiş bölünmüş yineleyicimi yazmaktır. Başka yolu var mı?
Streamdoğrudan arayüzde sunulur ve güzel basamaklı olması nedeniyle her işlem Streamtekrar verir . Birisinin size vermek istediğini düşünün, Streamancak zaten mapbunun gibi birkaç işlem uyguladı . Bir kullanıcı olarak, yine de paralel olarak yürütülüp yürütülmeyeceğine karar vermek istersiniz. Bu nedenle parallel(), akış zaten mevcut olsa da, yine de arama yapmanız mümkün olmalıdır .
flatMapveya iş parçacığı güvenli olmayan yöntemler veya benzeri çalıştırırsanız gibi kenar durumlar olduğunu anladım .
Pathyerel dosya sisteminde ve bir son JDK kullanıyoruz, spliterator bazı hatta karşı-üretken olabilirler 1024 Fakat dengeli bir bölme dozajları katları daha iyi paralel işlem yeteneğine sahip olacak findFirstsenaryolar ...
parallel()altta yatan akış nesnesine uygulanan genel bir değiştirici isteğinden başka bir şey değildir. Boruya son işlemleri uygulamadığınızda, yani hiçbir şey "yürütülmediği sürece" yalnızca bir kaynak akışının olduğunu unutmayın. Bunu söyledikten sonra, temelde sadece Java tasarım seçeneklerini sorguluyorsunuz. Hangi fikir tabanlı ve biz gerçekten bu konuda yardımcı olamaz.