เพื่อนที่ใช้แพ็คเกจพร้อมกันของ Java อาจคุ้นเคยกับอนาคต (อินเทอร์เฟซ) อนาคตได้รับการสนับสนุนโดยตรงที่ระดับไวยากรณ์ในบางภาษาโดเมน (เช่น Alice ML)
ที่นี่เราจะใช้ java.util.concurrent.future เป็นตัวอย่างในการพูดคุยสั้น ๆ เกี่ยวกับวิธีการทำงานเฉพาะของอนาคต วัตถุในอนาคตนั้นถือได้ว่าเป็นข้อมูลอ้างอิงที่ชัดเจนการอ้างอิงถึงผลลัพธ์ของการประมวลผลแบบอะซิงโครนัส เนื่องจากลักษณะแบบอะซิงโครนัสวัตถุที่อ้างอิงอาจไม่สามารถใช้ได้ตั้งแต่เริ่มต้นของการสร้าง (ตัวอย่างเช่นมันยังคงทำงานการส่งผ่านเครือข่ายหรือการรอคอย) ในเวลานี้หากโปรแกรมที่ได้รับในอนาคตไม่รีบร้อนที่จะใช้วัตถุที่อ้างอิงโดยอนาคตก็สามารถทำสิ่งอื่นที่คุณต้องการได้ เป็นสองสถานการณ์:
ฉันหวังว่าจะเห็นวัตถุนี้มีอยู่และดำเนินการตามกระบวนการติดตามที่เกี่ยวข้อง หากไม่สามารถใช้งานได้จริง ๆ คุณสามารถป้อนกระบวนการสาขาอื่น ๆ ได้
"ถ้าไม่มีคุณชีวิตของฉันจะสูญเสียความหมายดังนั้นแม้ว่าทะเลจะหายไปฉันจะรอคุณอยู่" (แน่นอนถ้าคุณไม่มีความเพียรที่จะรอ -เวลา)
สำหรับกรณีก่อนหน้านี้คุณสามารถตรวจสอบได้ว่าวัตถุที่อ้างอิงพร้อมโดยการโทรหา Future.isdone () และใช้การประมวลผลที่แตกต่างกัน
รับ (Long Timeout, TimeUnit Unit) รอให้วัตถุเตรียมพร้อมด้วยการปิดกั้นแบบซิงโครนัส ไม่ว่ารันไทม์จริงจะถูกบล็อกหรือส่งคืนทันทีขึ้นอยู่กับเวลาการโทรของ Get () และลำดับของวัตถุพร้อม
พูดง่ายๆคือโหมดในอนาคตสามารถตอบสนองความต้องการที่เกิดขึ้นพร้อมกันของข้อมูลในกระบวนการต่อเนื่องไม่เพียง แต่ได้รับการปรับปรุงประสิทธิภาพในการดำเนินการพร้อมกันเท่านั้น แต่ยังรวมถึงความเรียบง่ายและความสง่างามของกระบวนการต่อเนื่อง
เปรียบเทียบกับรูปแบบการออกแบบที่เกิดขึ้นพร้อมกันอื่น ๆ
นอกเหนือจากอนาคตรูปแบบการออกแบบพร้อมกันทั่วไปอื่น ๆ ยังรวมถึง "การเรียกโทรกลับ (ในสภาพแวดล้อมแบบมัลติเธรด)", "การขับเคลื่อนข้อความ/เหตุการณ์ (ในรูปแบบนักแสดง)" ฯลฯ
การโทรกลับเป็นโหมดการพร้อมกันแบบอะซิงโครนัสที่พบได้บ่อยที่สุดซึ่งมีการออกแบบอินเทอร์เฟซที่ง่ายและง่าย แต่เมื่อเทียบกับอนาคตข้อเสียของมันก็ชัดเจนมาก ขั้นแรกการเรียกกลับในสภาพแวดล้อมแบบมัลติเธรดจะถูกดำเนินการโดยทั่วไปในเธรดโมดูลที่กระตุ้นการโทรกลับซึ่งหมายความว่าปัญหาการยกเว้นของเธรดจะต้องได้รับการพิจารณาเมื่อเขียนวิธีการโทรกลับ เรียกใช้การเรียกกลับสำหรับแอปพลิเคชันผู้ใช้ซึ่งค่อนข้างไม่ปลอดภัยเนื่องจากคุณไม่สามารถกำหนดระยะเวลาหรือข้อยกเว้นที่จะเกิดขึ้นซึ่งอาจส่งผลกระทบทางอ้อมและความน่าเชื่อถือของโมดูลนี้ ลำดับ ดังนั้นอินเทอร์เฟซการโทรกลับจึงเหมาะสำหรับสถานการณ์ที่ต้องใช้งานง่าย ๆ ในการโทรกลับและไม่จำเป็นต้องรวมกับกระบวนการอื่น ๆ
ข้อเสียของโหมดการโทรกลับข้างต้นนั้นเป็นจุดแข็งของอนาคต เนื่องจากการใช้ในอนาคตคือการรวมตัวขับเคลื่อนข้อมูลแบบอะซิงโครนัสลงในกระบวนการตามลำดับคุณไม่จำเป็นต้องพิจารณาปัญหา Mutex ในอนาคต ถูกกล่าวถึงด้านล่าง "Lazy Future") ในทางกลับกันโมดูลที่ให้อินเทอร์เฟซในอนาคตไม่ต้องกังวลเกี่ยวกับปัญหาความน่าเชื่อถือเช่นอินเตอร์เฟสการโทรกลับและผลกระทบที่อาจเกิดขึ้นในโมดูลนี้
รูปแบบการออกแบบที่เกิดขึ้นพร้อมกันอีกประการหนึ่งคือ "ข้อความ (เหตุการณ์) ขับเคลื่อน" ซึ่งโดยทั่วไปจะใช้ในโมเดลนักแสดง: ผู้ร้องขอบริการส่งข้อความไปยังผู้ให้บริการและจากนั้นยังคงดำเนินการต่อไปซึ่งไม่พึ่งพาผลการประมวลผลบริการ และขึ้นอยู่กับว่าหากคุณต้องการพึ่งพามัน แม้ว่าการควบคุมที่เกิดขึ้นพร้อมกันของเครื่องนี้จะเหมาะสำหรับกระบวนการต่อเนื่องมากกว่าการโทรกลับ แต่นักพัฒนาต้องตัดกระบวนการต่อเนื่องให้เป็นกระบวนการย่อยเฉพาะหลายรัฐตามการเรียกของบริการแบบอะซิงโครนัสซึ่งเพิ่มความซับซ้อนของการพัฒนา การใช้โหมดในอนาคตสามารถหลีกเลี่ยงปัญหานี้และไม่ต้องทำลายกระบวนการต่อเนื่องสำหรับการโทรแบบอะซิงโครนัส อย่างไรก็ตามสิ่งหนึ่งที่ควรสังเกต: วิธีการในอนาคต get () อาจบล็อกการดำเนินการเธรดดังนั้นจึงมักจะไม่สามารถรวมเข้ากับโมเดลนักแสดงทั่วไปได้โดยตรง (โมเดลนักแสดงที่ใช้ Coroutine สามารถแก้ไขความขัดแย้งนี้ได้ดีขึ้น)
ความยืดหยุ่นของอนาคตนั้นสะท้อนให้เห็นถึงทางเลือกฟรีระหว่างการซิงโครไนซ์และตัวเลือกแบบอะซิงโครนัส ความต้องการของกระบวนการ ตัวอย่างเช่นคุณสามารถตัดสินใจได้ว่าจะใช้ช่องว่างนี้เพื่อทำภารกิจอื่น ๆ ให้เสร็จสมบูรณ์โดยพิจารณาจากว่าข้อมูลนั้นพร้อมหรือไม่ซึ่งค่อนข้างสะดวกสำหรับการใช้กลไกการทำนายสาขา "อะซิงโครนัส"
อนุพันธ์แห่งอนาคต
นอกเหนือจากรูปแบบพื้นฐานที่กล่าวถึงข้างต้นอนาคตยังมีการเปลี่ยนแปลงอนุพันธ์ที่หลากหลายดังนั้นนี่คือรูปแบบทั่วไปบางประการ
อนาคตขี้เกียจ
ซึ่งแตกต่างจากอนาคตทั่วไป Lazy Future ไม่ได้เริ่มเตรียมวัตถุอ้างอิงที่จุดเริ่มต้นของการสร้าง แต่รอจนกว่าจะมีการร้องขอวัตถุก่อนที่จะเริ่มงานที่เกี่ยวข้อง ดังนั้นอนาคตที่ขี้เกียจจึงไม่ได้มีวัตถุประสงค์เพื่อให้บรรลุพร้อมกัน แต่ใช้ทรัพยากรการคำนวณที่ไม่จำเป็นเป็นจุดเริ่มต้นและผลกระทบของมันคล้ายกับแลมบ์ดา/การปิด ตัวอย่างเช่นเมื่อออกแบบ API บางอย่างคุณอาจต้องส่งคืนชุดข้อมูลและการคำนวณบางส่วนอาจใช้ทรัพยากรจำนวนมาก อย่างไรก็ตามผู้โทรอาจไม่กังวลเกี่ยวกับข้อมูลทั้งหมดนี้ดังนั้นการจัดหาวัตถุที่ต้องการทรัพยากรมากขึ้นในรูปแบบของอนาคตที่ขี้เกียจสามารถประหยัดทรัพยากรได้เมื่อผู้โทรไม่จำเป็นต้องใช้ข้อมูลเฉพาะ
นอกจากนี้ยังสามารถใช้อนาคตที่ขี้เกียจเพื่อหลีกเลี่ยงการยกเว้นซึ่งกันและกันที่ไม่จำเป็นซึ่งเกิดจากการได้มาก่อนกำหนดหรือล็อคทรัพยากร
สัญญา
สัญญาอาจถือได้ว่าเป็นสาขาพิเศษของอนาคต แต่สัญญาถูกนำมาใช้เพื่อแสดงสถานการณ์อย่างชัดเจนโดยที่กระบวนการแบบอะซิงโครนัสไม่ได้ถูกเรียกโดยตรงโดยผู้เรียกบริการ ตัวอย่างเช่นการควบคุมเวลาของอินเทอร์เฟซในอนาคตกระบวนการแบบอะซิงโครนัสนั้นไม่ได้ถูกกระตุ้นโดยผู้โทร แต่โดยนาฬิการะบบ สมาชิก แต่โดยสมาชิก ดังนั้นเมื่อเทียบกับอนาคตมาตรฐานส่วนต่อประสานสัญญาโดยทั่วไปจะมีชุดอินเทอร์เฟซพิเศษ () หรือเติมเต็ม () อินเทอร์เฟซ
อนาคตที่นำกลับมาใช้ใหม่
อนาคตปกติคือครั้งเดียวซึ่งหมายความว่าเมื่อคุณได้รับผลการประมวลผลแบบอะซิงโครนัสวัตถุในอนาคตจะสูญเสียความหมาย แต่อนาคตที่ออกแบบมาเป็นพิเศษสามารถนำกลับมาใช้ใหม่ซึ่งมีประโยชน์มากสำหรับข้อมูลที่สามารถเปลี่ยนแปลงได้หลายครั้ง ตัวอย่างเช่นอินเทอร์เฟซสไตล์ในอนาคตที่จัดทำโดยกรอบการสมัครสมาชิก Taobao Distributed ที่กล่าวถึงข้างต้นอนุญาตให้มีการโทรหลายครั้งไปยังวิธี Waitnext () (เทียบเท่ากับ Future.get () การโทรครั้งสุดท้าย ข้อได้เปรียบของการออกแบบนี้คือผู้ใช้ของอินเทอร์เฟซสามารถตอบสนองต่อการเปลี่ยนแปลงข้อมูลการสมัครสมาชิกในเวลาที่เหมาะสมหรือเพียงแค่ผ่านลูปที่ไม่มีที่สิ้นสุดในเธรดอิสระในขณะเดียวกันก็คำนึงถึงงานเวลาอื่น ๆ หรือแม้แต่รองานหลายงาน ในเวลาเดียวกัน ตัวอย่างที่ง่ายขึ้นมีดังนี้:
สำหรับ (;;) {schedule = getNextScheduledTasktime (); .}} doscheduledTask ();} การใช้อนาคต
ก่อนอื่นให้แสดงรายการรหัสในการคิดใน Java
//: concurrency/callabledemo.javaimport java.util.concurrent.*; นำเข้า java.util.*; class taskwithresult ดำเนินการ callable <string> {ID INT ส่วนตัว; การเรียกสตริง () {return "ผลลัพธ์ของ TaskWithResult" + id;}} คลาสสาธารณะ callabledemo {โมฆะสาธารณะคง ใหม่ ArrayList <Future <string>> (); พยายาม : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : ::::::::::::::::::::::: กระทาน ::::::::::::::::::::::::::::::::::::::::: กระทาน. ; : ผลของ taskwithresult 0result ของ taskwithresult 1result ของ taskwithresult 2res ult of taskresult 3 result ของ taskwithresult 4result ของ taskwithresult 5 result ของ taskwithresult 6result ของ taskwithresultเพื่ออธิบายการใช้ในอนาคตก่อนอื่นวิธี ExecutorService Object EXEC SUND SUND () เพื่อสร้างวัตถุในอนาคตซึ่งใช้ประเภทเฉพาะของผลลัพธ์การส่งคืนที่เรียกได้เพื่อกำหนดพารามิเตอร์ คุณสามารถใช้วิธีการ ISDONE () เพื่อสอบถามว่าอนาคตจะเสร็จสมบูรณ์หรือไม่ เมื่องานเสร็จสมบูรณ์จะมีผลลัพธ์และคุณสามารถโทรหาวิธีการรับ () เพื่อรับผลลัพธ์ นอกจากนี้คุณยังสามารถโทรหา () โดยตรงโดยไม่ต้องตรวจสอบ ISDONE () คุณสามารถโทรหาฟังก์ชั่น Get () ด้วยการหมดเวลาหรือโทร IsDone () ก่อนเพื่อดูว่างานเสร็จสมบูรณ์หรือไม่จากนั้นโทรหา ()