“สวัสดี อามีโก้!”

"มีหัวข้อใหญ่อยู่ข้างนอก นั่นคือ Java Memory Model โดยพื้นฐานแล้ว คุณไม่จำเป็นต้องรู้เกี่ยวกับเรื่องนี้ แต่การได้ยินเกี่ยวกับเรื่องนี้จะเป็นประโยชน์"

"เพื่อขจัดปัญหาที่อาจเกิดขึ้นทั้งหมด Java ได้เปลี่ยนกลไกการจัดการหน่วยความจำ ตอนนี้หน่วยความจำไม่ได้ถูกแบ่งออกเป็นแคชในเครื่องของเธรดและหน่วยความจำส่วนกลางเท่านั้น กลไกนี้ดียิ่งขึ้นไปอีก"

"และซับซ้อนกว่านั้น!"

"ใช่ ดีกว่าและซับซ้อนกว่า มันเหมือนกับเครื่องบิน การบินโดยเครื่องบินดีกว่าการเดิน แต่ซับซ้อนกว่า ฉันจะพยายามอธิบายสถานการณ์ใหม่อย่างเรียบง่าย"

"นี่คือสิ่งที่พวกเขาคิดขึ้นกลไกสำหรับการซิงโครไนซ์หน่วยความจำเธรดโลคัลที่เรียกว่า 'happens-before' ถูกเพิ่มเข้าไปในโค้ด มีการคิดค้นกฎ/เงื่อนไขหลายอย่าง เมื่อเงื่อนไขเหล่านี้ตรงตามเงื่อนไข หน่วยความจำจะถูกซิงโครไนซ์หรืออัปเดตเป็นปัจจุบัน สถานะ.

"นี่คือตัวอย่าง:"

คำสั่ง หัวข้อที่ 1 หัวข้อที่ 2
1
2

101
102
103
104
105

201
202
203
204
205
public int y = 1;
public int x = 1;

x = 2;
synchronized(mutex)
{
 y = 2;
}
เธรดกำลังรอการเผยแพร่ mutex

synchronized(mutex)
{
 if (y == x)
 System.out.println("YES");
}

"หนึ่งในเงื่อนไขเหล่านี้คือการได้มาของ mutex ที่ปล่อยออกมา ถ้า mutex ถูกปล่อยและได้มาอีกครั้ง หน่วยความจำจะถูกซิงโครไนซ์ก่อนการได้มา เธรด 2 จะเห็นค่า 'ล่าสุด' ของตัวแปร x และ y แม้ว่า คุณไม่ได้ประกาศว่าพวกเขาไม่แน่นอน"

"น่าสนใจจัง! และมีเงื่อนไขแบบนี้ด้วยเหรอ?"

"พอแล้ว ต่อไปนี้เป็นเงื่อนไขบางประการสำหรับการซิงโครไนซ์หน่วยความจำ:"

  • "ภายในเธรดเดียว คำสั่งใดๆจะเกิดขึ้นก่อนการดำเนินการใดๆ ที่ตามมาในซอร์สโค้ด"
  • "การปลดล็อคเกิดขึ้นก่อนที่จะได้ล็อคแบบเดียวกัน"
  • "การออกจากบล็อก/เมธอด  ที่ซิงโครไน ซ์ เกิดขึ้น - ก่อนที่บล็อก/เมธอดที่ซิงโครไนซ์จะถูกป้อนบนหน้าจอเดียวกัน"
  • "การเขียนฟิลด์ลบเลือนไปยังหน่วยความจำเกิดขึ้นก่อนที่ฟิลด์ลบเลือนเดียวกันจะถูกอ่านจากหน่วยความจำ"
  • "การสิ้นสุดของเมธอดการรันของอ็อบเจกต์เธรดเกิดขึ้นก่อนที่เมธอด join() จะสิ้นสุดลง หรือเมธอด isAlive() จะส่งกลับค่าเท็จบนอ็อบเจกต์ในเธรดเดียวกัน"
  • "การเรียกใช้เมธอด start() ของวัตถุเธรดเกิดขึ้นก่อนที่เมธอด run() จะเริ่มต้นบนวัตถุในเธรดเดียวกัน"
  • "การสิ้นสุดของคอนสตรัคเตอร์เกิดขึ้นก่อนการเริ่มต้นเมธอด Finalize() ของคลาสนี้"
  • "การเรียกเมธอดอินเทอร์รัปต์ () เกิดขึ้นก่อนที่เธรดจะระบุว่าเมธอดนี้ถูกเรียก อาจเป็นเพราะ InterruptedException ถูกโยนทิ้ง หรือโดยการใช้เมธอด isInterrupted() หรืออินเทอร์รัปต์ ()"

“แล้วมันซับซ้อนกว่าที่ฉันคิดไว้นิดหน่อยเหรอ?”

“ใช่ ซับซ้อนกว่านั้นนิดหน่อย…”

“ขอบใจนะฤๅษี ฉันจะคิดดู”

“อย่ากังวลกับหัวข้อนี้มากนัก เวลาจะมาถึงเมื่อเจ้าจะเข้าใจมันทั้งหมดด้วยตัวท่านเอง สำหรับตอนนี้ มันจะดีกว่าที่เจ้าจะเข้าใจพื้นฐานมากกว่าที่จะเจาะลึกเข้าไปในป่าทึบที่เป็น การทำงานภายในของเครื่อง Java Java 9 จะถูกปล่อยออกมาและทุกอย่างจะเปลี่ยนไปอีกครั้ง"

"O_o ใช่แล้ว... บางสิ่งไม่ควรรู้จะดีกว่า"