ที่จริงฉันใช้เวลาศึกษาแหล่งที่มาจริงจากความอยากรู้อยากเห็นและความคิดที่อยู่เบื้องหลังมันค่อนข้างง่าย รุ่นล่าสุดในขณะเขียนโพสต์นี้คือ 3.2.1
มีบัฟเฟอร์ที่จัดเก็บเหตุการณ์ที่จัดสรรไว้ล่วงหน้าซึ่งจะเก็บข้อมูลไว้ให้ผู้บริโภคอ่าน
บัฟเฟอร์ได้รับการสนับสนุนโดยอาร์เรย์ของธง (อาร์เรย์จำนวนเต็ม) ของความยาวที่อธิบายถึงความพร้อมใช้งานของช่องบัฟเฟอร์ (ดูรายละเอียดเพิ่มเติม) มีการเข้าถึงอาร์เรย์เช่น java # AtomicIntegerArray ดังนั้นเพื่อจุดประสงค์ในการอธิบายนี้คุณอาจถือว่ามันเป็นหนึ่ง
อาจมีผู้ผลิตจำนวนเท่าใดก็ได้ เมื่อผู้ผลิตต้องการเขียนลงในบัฟเฟอร์จะมีการสร้างจำนวนที่ยาวขึ้น (เช่นเดียวกับในการเรียก AtomicLong # getAndIncrement, Disruptor ใช้การใช้งานจริงของตัวเอง แต่ทำงานในลักษณะเดียวกัน) เราเรียกสิ่งนี้ว่า ในทำนองเดียวกัน ConsumerCallId จะถูกสร้างขึ้นเมื่อ consumer ENDS อ่านสล็อตจากบัฟเฟอร์ เข้าถึง ConsumerCallId ล่าสุด
(หากมีผู้บริโภคจำนวนมากการโทรที่มี id ต่ำสุดจะถูกเลือก)
รหัสเหล่านี้จะถูกนำมาเปรียบเทียบและหากความแตกต่างระหว่างสองน้อยกว่าด้านบัฟเฟอร์ผู้ผลิตได้รับอนุญาตให้เขียน
(ถ้า producerCallId มากกว่า ConsumerCallId + bufferSize ล่าสุดแสดงว่าบัฟเฟอร์เต็มและผู้ผลิตถูกบังคับให้รอจนกระทั่งบัสว่าง)
โปรดิวเซอร์ได้รับการกำหนดสล็อตในบัฟเฟอร์ตาม callId ของเขา (ซึ่งคือ prducerCallId modulo bufferSize แต่เนื่องจาก bufferSize อยู่เสมอกำลังของ 2 (จำกัด บังคับใช้กับการสร้างบัฟเฟอร์) การดำเนินการ actuall ที่ใช้คือ producerCallId & (bufferSize - 1 )) จากนั้นจะสามารถแก้ไขเหตุการณ์ในสล็อตนั้นได้ฟรี
(อัลกอริทึมที่เกิดขึ้นจริงนั้นซับซ้อนกว่าเล็กน้อยซึ่งเกี่ยวข้องกับการแคช ConsumerId ล่าสุดในการอ้างอิงอะตอมมิกแยกกันเพื่อจุดประสงค์ในการปรับให้เหมาะสม)
เมื่อเหตุการณ์มีการแก้ไขการเปลี่ยนแปลงคือ "เผยแพร่" เมื่อเผยแพร่สล็อตตามลำดับในอาร์เรย์แฟล็กจะเต็มไปด้วยแฟล็กที่อัพเดต ค่าแฟล็กคือจำนวนของลูป (producerCallId หารด้วย bufferSize (อีกครั้งเนื่องจาก bufferSize คือกำลัง 2 การดำเนินการจริงคือการเปลี่ยนแปลงที่ถูกต้อง)
ในทำนองเดียวกันอาจมีผู้บริโภคจำนวนเท่าใดก็ได้ ทุกครั้งที่ผู้บริโภคต้องการเข้าถึงบัฟเฟอร์ consumerCallId จะถูกสร้างขึ้น (ขึ้นอยู่กับวิธีที่ผู้บริโภคถูกเพิ่มเข้าไปในเครื่องทำลายอะตอมที่ใช้ในการสร้างรหัสอาจถูกแชร์หรือแยกกันสำหรับแต่ละรายการ) consumerCallId นี้จะถูกเปรียบเทียบกับ producentCallId ล่าสุดและหากน้อยกว่าสองรายการผู้อ่านจะได้รับอนุญาตให้ดำเนินการต่อไป
(ในทำนองเดียวกันถ้า producerCallId ยังคงเป็น consumerCallId ก็หมายความว่าบัฟเฟอร์นั้นมีคุณสมบัติและผู้บริโภคถูกบังคับให้รอลักษณะของการรอจะถูกกำหนดโดย WaitStrategy ในระหว่างการสร้าง disruptor)
สำหรับผู้บริโภครายบุคคล (ผู้ที่มีตัวสร้างรหัสของตัวเอง) สิ่งต่อไปที่ตรวจสอบคือความสามารถในการใช้แบทช์ สล็อตในบัฟเฟอร์ถูกตรวจสอบตามลำดับจากรายการที่สัมพันธ์กับ consumerCallId (ดัชนีถูกกำหนดในลักษณะเดียวกับผู้ผลิต) ไปยังรายการที่เกี่ยวข้องกับ producerCallId ล่าสุด
พวกเขาจะถูกตรวจสอบในวงโดยการเปรียบเทียบค่าสถานะที่เขียนในอาร์เรย์ธงกับค่าสถานะที่สร้างขึ้นสำหรับ ConsumerCallId หากธงตรงกันนั่นหมายความว่าผู้ผลิตที่เติมช่องได้ยอมรับการเปลี่ยนแปลงของพวกเขา ถ้าไม่ใช่ลูปจะถูกทำลายและจะส่งคืน changeId ที่คอมมิตที่ยอมรับสูงสุด สล็อตจาก ConsumerCallId ถึงได้รับใน changeId สามารถบริโภคเป็นชุด
หากกลุ่มผู้บริโภคอ่านด้วยกัน (กลุ่มที่มีตัวสร้าง id ที่แชร์) แต่ละคนจะรับ callId เพียงครั้งเดียวและเฉพาะสล็อตสำหรับ callId นั้นเท่านั้นที่จะถูกตรวจสอบและส่งคืน