บางครั้งการเพิ่มประสิทธิภาพของคอมไพเลอร์และโปรเซสเซอร์จะทำให้รันไทม์แตกต่างจากสิ่งที่เราจินตนาการ ด้วยเหตุนี้ Java จึงกำหนดข้อ จำกัด บางประการเกี่ยวกับคอมไพเลอร์และโปรเซสเซอร์ โมเดลหน่วยความจำ Java (JMM) เป็นบทสรุปสิ่งเหล่านี้เพื่อไม่ให้พิจารณารายละเอียดพื้นฐานมากมายเมื่อเขียนโค้ดและทำให้มั่นใจได้ว่า "ตราบใดที่คุณทำตามกฎ JMM เพื่อเขียนโปรแกรมผลการทำงานจะต้องถูกต้อง"
โครงสร้างบทคัดย่อของ JMM
ใน Java ทุกกรณีและตัวแปรคงที่จะถูกเก็บไว้ในหน่วยความจำฮีปซึ่งสามารถแชร์ระหว่างเธรดและส่วนนี้เรียกว่า ตัวแปรที่ใช้ร่วมกัน ตัวแปรท้องถิ่นพารามิเตอร์นิยามวิธีการและพารามิเตอร์การจัดการข้อยกเว้นอยู่บนสแต็กและหน่วยความจำสแต็กไม่ได้แชร์ระหว่างเธรด
อย่างไรก็ตามเนื่องจากการเพิ่มประสิทธิภาพของคอมไพเลอร์และโปรเซสเซอร์จะมีปัญหาการมองเห็นกับตัวแปรที่ใช้ร่วมกัน ตัวอย่างเช่นในหลายโปรเซสเซอร์เธรดสามารถดำเนินการกับโปรเซสเซอร์ที่แตกต่างกันและ แคชที่ไม่สอดคล้องกันระหว่างโปรเซสเซอร์จะทำให้เกิดปัญหาการมองเห็นด้วยตัวแปรที่ใช้ร่วมกัน เป็นไปได้ว่าสองเธรดจะเห็นค่าที่แตกต่างกันของตัวแปรเดียวกัน
jmm abstracts การเพิ่มประสิทธิภาพที่ทำโดยฮาร์ดแวร์เหล่านี้ในแต่ละเธรดมีหน่วยความจำท้องถิ่น เมื่อคุณต้องการอ่านและเขียนตัวแปรที่ใช้ร่วมกันคัดลอกสำเนาจากหน่วยความจำหลักไปยังหน่วยความจำท้องถิ่น เมื่อเขียนตัวแปรที่ใช้ร่วมกันให้เขียนลงในหน่วยความจำท้องถิ่นก่อนจากนั้นรีเฟรชพวกเขาไปยังหน่วยความจำหลักในบางช่วงเวลาในอนาคต เมื่ออ่านตัวแปรที่ใช้ร่วมกันอีกครั้งมันจะถูกอ่านจากหน่วยความจำท้องถิ่นเท่านั้น
ด้วยวิธีนี้การสื่อสารระหว่างเธรดต้องใช้สองขั้นตอน:
เธรดเขียน: รีเฟรชหน่วยความจำโลคัลและอ่านเธรด: อ่านค่าที่อัปเดตจากหน่วยความจำหลัก
ด้วยวิธีนี้มีความล่าช้าระหว่างการเขียนและการอ่าน: หน่วยความจำท้องถิ่นจะถูกรีเฟรชเมื่อใดที่หน่วยความจำหลัก? สิ่งนี้นำไปสู่ปัญหาการมองเห็นและเธรดที่แตกต่างกันอาจเห็นตัวแปรที่ใช้ร่วมกันที่แตกต่างกัน
เกิดขึ้นก่อน
เกิดขึ้นจริง-ก่อนหน้านี้หมายถึง "ก่อนเกิดขึ้นก่อนหน้านี้" นี่คือกฎที่ Java กำหนดตามลำดับของการดำเนินการโปรแกรมและต้องปฏิบัติตามการซิงโครไนซ์ ด้วยวิธีนี้โปรแกรมเมอร์จะต้องเขียนโปรแกรมซิงโครนัสที่ถูกต้องเท่านั้นและเกิดขึ้นก่อนหน้านี้เพื่อให้มั่นใจว่าผลลัพธ์การทำงานจะไม่ผิด
เกิดขึ้นก่อนที่ B ไม่เพียง แต่หมายความว่า A ถูกดำเนินการก่อน B แต่ยังหมายความว่าผลการดำเนินการของ A สามารถมองเห็นได้กับ B ซึ่งทำให้มั่นใจได้ว่าการมองเห็น
เกิดขึ้นก่อน B, A ไม่จำเป็นต้องดำเนินการก่อน B. หาก AB สลับกันและผลการดำเนินการยังคงถูกต้องคอมไพเลอร์และโปรเซสเซอร์จะได้รับอนุญาตให้ปรับลำดับใหม่ให้เหมาะสม ดังนั้นตราบใดที่ผลลัพธ์ของโปรแกรมถูกต้องไม่มีปัญหาเกี่ยวกับวิธีการที่คอมไพเลอร์และโปรเซสเซอร์เพิ่มประสิทธิภาพและสั่งซื้อใหม่และมันก็ดีทั้งหมด
เกิดขึ้นก่อนกฎ
กฎลำดับของโปรแกรม: ในเธรดกฎการล็อคการดำเนินการหลังจากการดำเนินการก่อนหน้านี้เกิดขึ้นก่อน: สำหรับการล็อคเดียวกันปลดล็อคเกิดขึ้นก่อนและล็อคกฎโดเมนที่ผันผวน: เขียนตัวแปรผันผวนและอ่านตัวแปรระเหยง่ายหลังจากเกิดขึ้นก่อน การเปลี่ยนแปลงของการดำเนินการ: เกิดขึ้นก่อน b, b เกิดขึ้นก่อน c จากนั้นจะเกิดขึ้นก่อน c start () กฎ: ถ้าเธรด A ดำเนินการเธรด start () จากนั้น threadb.start () เกิดขึ้นก่อนการดำเนินการใด ๆ เข้าร่วม () กฎในเธรด B: หากเธรดดำเนินการ Threadb.join ()
ตัวอย่างต่อไปนี้ช่วยให้เข้าใจเกิดขึ้นก่อน
double pi = 3.14; // adouble r = 1.0; // พื้นที่ bdouble = pi * r * r; // C
นี่คือสามสิ่งที่เกิดขึ้นก่อนความสัมพันธ์กฎ 1 และ 2 เป็นกฎการสั่งซื้อของโปรแกรมและกฎ 3 มาจากกฎสกรรมกริยา:
เกิดขึ้นก่อนที่ bb จะเกิดขึ้นก่อนที่จะเกิดขึ้นก่อน c
C ขึ้นอยู่กับ A และ B แต่ไม่ได้ขึ้นอยู่กับมัน ดังนั้นแม้ว่า A และ B จะถูกจัดลำดับใหม่ผลลัพธ์การดำเนินการจะไม่เปลี่ยนแปลง ในการจัดลำดับใหม่นี้ JMM กำลังทำงานอยู่
ลำดับการดำเนินการสองรายการต่อไปนี้ถูกต้อง
ข้างต้นคือเนื้อหาทั้งหมดที่เรารวบรวมไว้สำหรับคุณเกี่ยวกับการเรียนรู้โมเดลหน่วยความจำ Java JMM สำหรับคำถามเพิ่มเติมโปรดฝากข้อความไว้ด้านล่างเพื่อพูดคุย ขอบคุณสำหรับการสนับสนุน Wulin.com