AtomicInteger recordNumber = new AtomicInteger();
Files.lines(inputFile.toPath(), StandardCharsets.UTF_8)
.map(record -> new Record(recordNumber.incrementAndGet(), record))
.parallel()
.filter(record -> doSomeOperation())
.findFirst()
เมื่อฉันเขียนสิ่งนี้ฉันสันนิษฐานว่าเธรดจะวางไข่เฉพาะการเรียกแผนที่เนื่องจากวางขนานหลังจากแผนที่ แต่บางบรรทัดในไฟล์ได้รับหมายเลขบันทึกที่แตกต่างกันสำหรับการดำเนินการทุกครั้ง
ฉันอ่านเอกสาร Java streamอย่างเป็นทางการและเว็บไซต์บางแห่งเพื่อทำความเข้าใจวิธีการทำงานของสตรีมภายใต้ฮูด
คำถามเล็กน้อย:
Java กระแสขนานทำงานบนพื้นฐานของSplitIteratorซึ่งดำเนินการโดยคอลเลกชันทุกอย่างเช่น ArrayList, LinkedList เป็นต้นเมื่อเราสร้างสตรีมขนานจากคอลเลกชันเหล่านั้นตัววนซ้ำที่สอดคล้องกันนั้นจะถูกใช้เพื่อแยกและย้ำคอลเลกชัน สิ่งนี้อธิบายว่าเหตุใดจึงเกิดความขนานที่แหล่งอินพุตดั้งเดิม (เส้นไฟล์) แทนที่จะเป็นผลลัพธ์ของแผนที่ (เช่นเร็กคอร์ด pojo) ความเข้าใจของฉันถูกต้องหรือไม่
ในกรณีของฉันอินพุตเป็นไฟล์สตรีม IO จะใช้ตัววนซ้ำแบบแยกใด
ไม่สำคัญว่าเราจะวางไว้ที่ไหน
parallel()
ในท่อส่ง แหล่งอินพุตดั้งเดิมจะถูกแยกเสมอและจะใช้การดำเนินการระดับกลางที่เหลืออยู่ในกรณีนี้ Java ไม่ควรอนุญาตให้ผู้ใช้ทำการดำเนินการแบบขนานที่ใดก็ได้ในไปป์ไลน์ยกเว้นที่แหล่งต้นฉบับ เนื่องจากเป็นการให้ความเข้าใจที่ผิดสำหรับผู้ที่ไม่ทราบว่า java stream ทำงานอย่างไรภายใน ฉันรู้ว่า
parallel()
การดำเนินการจะได้รับการกำหนดไว้สำหรับประเภทวัตถุสตรีมและดังนั้นจึงทำงานได้ด้วยวิธีนี้ แต่มันจะดีกว่าที่จะให้ทางออกทางเลือกบางอย่างในตัวอย่างโค้ดข้างต้นฉันพยายามเพิ่มหมายเลขบรรทัดในทุกเร็กคอร์ดในไฟล์อินพุตดังนั้นควรสั่งซื้อ อย่างไรก็ตามฉันต้องการนำไปใช้
doSomeOperation()
ควบคู่กันเพราะเป็นตรรกะที่มีน้ำหนักมาก วิธีหนึ่งในการบรรลุคือการเขียนตัวแยกซ้ำที่กำหนดเองของฉัน มีวิธีอื่น ๆ ?
Stream
อินเตอร์เฟสโดยตรงและเนื่องจากการเชื่อมต่อที่ดีทุกการดำเนินการกลับมาStream
อีกครั้ง ลองนึกภาพใครบางคนที่ต้องการให้คุณStream
ได้ใช้การดำเนินการสองสามอย่างเช่นmap
นี้ คุณในฐานะผู้ใช้ยังคงต้องการที่จะตัดสินใจว่าจะให้มันทำงานแบบขนานหรือไม่ ดังนั้นจึงเป็นไปได้ที่คุณจะparallel()
ยังคงโทรถึงแม้ว่าสตรีมจะมีอยู่แล้ว
flatMap
หรือถ้าคุณดำเนินการวิธีการเธรดที่ไม่ปลอดภัยหรือคล้ายกัน
Path
อยู่ในระบบไฟล์ในเครื่องและคุณกำลังใช้ JDK เมื่อเร็ว ๆ นี้ตัวแยกสัญญาณจะมีความสามารถในการประมวลผลแบบขนานที่ดีกว่าการสร้างชุดข้อมูลทวีคูณที่ 1024 แต่การแบ่งแบบสมดุลอาจจะตอบโต้ได้ในบางfindFirst
สถานการณ์ ...
parallel()
ไม่มีอะไรมากไปกว่าการร้องขอโมดิฟายเออร์ทั่วไปซึ่งใช้กับวัตถุสตรีมที่สำคัญ โปรดจำไว้ว่ามีเพียงสตรีมต้นทางหนึ่งรายการหากคุณไม่ได้ใช้การดำเนินการขั้นสุดท้ายกับไปป์นั่นคือตราบใดที่ไม่มีการ "ดำเนินการ" ต้องบอกว่าคุณแค่ตั้งคำถามเกี่ยวกับตัวเลือกการออกแบบ Java ซึ่งเป็นพื้นฐานของความคิดเห็นและเราไม่สามารถช่วยได้จริงๆ