1. ส่งคืนข้อมูลผ่านตัวแปรคลาสและวิธีการ
การใช้เมธอดนี้เพื่อส่งคืนข้อมูลจำเป็นต้องเรียกใช้เมธอด start ก่อนจึงจะสามารถรับข้อมูลผ่านตัวแปรคลาสหรือเมธอดได้ ก่อนอื่นเรามาดูกันว่าเราได้ผลลัพธ์อะไรบ้างจากตัวอย่างที่ 2-13
คัดลอกรหัสรหัสดังต่อไปนี้:
ตำนานแพ็คเกจ;
MyThread คลาสสาธารณะขยายเธรด
-
ค่าสตริงส่วนตัว1;
ค่าสตริงส่วนตัว2;
การรันโมฆะสาธารณะ ()
-
value1 = "ส่งคืนข้อมูลผ่านตัวแปรสมาชิก";
value2 = "ส่งคืนข้อมูลด้วยวิธีสมาชิก";
-
โมฆะคงที่สาธารณะ main (String [] args) พ่นข้อยกเว้น
-
เธรด MyThread = MyThread ใหม่ ();
เธรด.เริ่มต้น();
System.out.println("value1:" + thread.value1);
System.out.println("value2:" + thread.value2);
-
-
การรันโค้ดด้านบนอาจให้ผลลัพธ์ดังต่อไปนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
ค่า1:เป็นโมฆะ
ค่า2:เป็นโมฆะ
ผลการวิ่งข้างต้นดูผิดปกติมาก ค่าถูกกำหนดให้กับค่า 1 และค่า 2 ในวิธีการรัน แต่ส่งคืนค่า null สาเหตุที่เกิดเหตุการณ์เช่นนี้คือค่าของ value1 และ value2 จะถูกส่งออกทันทีหลังจากเรียกเมธอด start และวิธีการ run ที่นี่ยังไม่ได้ดำเนินการคำสั่งที่กำหนดค่าให้กับ value1 และ value2 เพื่อหลีกเลี่ยงสถานการณ์นี้ คุณต้องรอจนกว่าวิธีการเรียกใช้จะถูกดำเนินการก่อนที่จะดำเนินการโค้ดที่ส่งออกค่า 1 และค่า 2 ดังนั้นเราจึงสามารถคิดถึงการใช้วิธี sleep เพื่อชะลอเธรดหลักได้ ตัวอย่างเช่น เราสามารถเพิ่มคำสั่งต่อไปนี้หลัง thread.start():
นอนหลับ(1,000);
การทำเช่นนี้อาจทำให้เธรดหลักล่าช้าเป็นเวลา 1 วินาทีก่อนที่จะดำเนินการต่อ แต่มีปัญหาในเรื่องนี้คือเราจะรู้ได้อย่างไรว่าจะต้องดีเลย์นานแค่ไหน ในตัวอย่างนี้ มีเพียงสองคำสั่งการกำหนดในวิธีการรัน และมีเพียงเธรดเดียวเท่านั้นที่ถูกสร้างขึ้น ดังนั้น การหน่วงเวลา 1 วินาทีก็เพียงพอแล้ว แต่ถ้าคำสั่งในวิธีการรันนั้นซับซ้อน เวลานี้เป็นเรื่องยากที่จะคาดเดา ดังนั้นวิธีนี้จึงไม่เสถียร
จุดประสงค์ของเราคือการรับค่าของ value1 และ value2 ดังนั้นเราเพียงแต่ต้องพิจารณาว่า value1 และ value2 เป็นโมฆะหรือไม่ หากไม่มีค่าใดเป็นค่าว่าง ก็สามารถส่งออกค่าทั้งสองนี้ได้ เราสามารถใช้โค้ดต่อไปนี้เพื่อให้บรรลุวัตถุประสงค์นี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
ในขณะที่ (thread.value1 == null || thread.value2 == null);
การใช้คำสั่งข้างต้นสามารถหลีกเลี่ยงสถานการณ์นี้ได้อย่างเสถียร แต่วิธีนี้ใช้ทรัพยากรระบบมากเกินไป คุณคงจินตนาการได้ว่าถ้าโค้ดในวิธีการ run ซับซ้อนมาก ค่า 1 และค่า 2 จะใช้เวลานานในการกำหนด ดังนั้น while จะต้องดำเนินการต่อไปจนกว่าทั้งค่า 1 และค่า 2 จะไม่ว่างเปล่า ดังนั้นเราจึงสามารถปรับปรุงข้อความข้างต้นได้ดังต่อไปนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
ในขณะที่ (thread.value1 == null || thread.value2 == null)
นอน(100);
ใน while loop หลังจากตัดสินค่าของ value1 และ value2 เป็นครั้งแรก มันจะพักเป็นเวลา 100 มิลลิวินาที จากนั้นจึงตัดสินทั้งสองค่านี้ สิ่งนี้จะใช้ทรัพยากรระบบน้อยลง
แม้ว่าวิธีการข้างต้นจะสามารถแก้ไขได้ดีมาก แต่โมเดลเธรดของ Java ก็ให้วิธีแก้ปัญหาที่ดีกว่าแก่เรา ซึ่งก็คือวิธีการรวม ตามที่กล่าวไว้ก่อนหน้านี้ ฟังก์ชันของการรวมคือการใช้เธรดเพื่อเปลี่ยนจากการดำเนินการแบบอะซิงโครนัสเป็นการดำเนินการแบบซิงโครนัส เมื่อเธรดถูกดำเนินการแบบซิงโครนัส ก็ไม่ต่างจากการรับข้อมูลที่ส่งคืนจากวิธีการทั่วไป ดังนั้นปัญหานี้สามารถแก้ไขได้อย่างมีประสิทธิภาพมากขึ้นโดยใช้โค้ดดังต่อไปนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
เธรด.เริ่มต้น();
เธรด.เข้าร่วม();
หลังจากดำเนินการ thread.join() แล้ว วิธีการรันของเธรดเธรดจะสิ้นสุดลง ซึ่งหมายความว่าเธรดเธรดได้สิ้นสุดลงแล้ว ดังนั้น คุณสามารถใช้ทรัพยากรใดๆ ของคลาส MyThread หลังจาก thread.join() เพื่อรับข้อมูลที่ส่งคืนได้อย่างปลอดภัย
2. ส่งคืนข้อมูลผ่านฟังก์ชันโทรกลับ
อันที่จริงแล้ว วิธีการนี้ได้ถูกนำมาใช้ใน "Three Methods of Passing Data to Threads" ในตัวอย่างของบทความ "สามวิธีในการส่งข้อมูลไปยังเธรด" ผลลัพธ์การคำนวณจะถูกส่งผ่านไปยังเธรดผ่านวิธีกระบวนการของคลาสงาน แต่ในขณะเดียวกันก็ได้รับตัวเลขสุ่มสามตัวจากเธรดผ่าน วิธีการประมวลผล ดังนั้นวิธีนี้จึงสามารถส่งข้อมูลไปยังและรับข้อมูลจากเธรดได้